Je suis conscient que le concept d'invariants existe dans plusieurs paradigmes de programmation. Par exemple, les invariants de boucle sont pertinents en OO, en programmation fonctionnelle et procédurale.
Cependant, un type très utile trouvé dans la POO est un invariant des données d'un type particulier. C'est ce que j'appelle des "invariants basés sur le type" dans le titre. Par exemple, un Fraction
type peut avoir un numerator
et denominator
, avec l'invariant que leur pgcd est toujours 1 (c'est-à-dire que la fraction est sous une forme réduite). Je ne peux garantir cela qu'en ayant une sorte d'encapsulation du type, sans laisser ses données être définies librement. En retour, je n'ai jamais à vérifier si elle est réduite, je peux donc simplifier les algorithmes comme les contrôles d'égalité.
D'un autre côté, si je déclare simplement un Fraction
type sans fournir cette garantie par encapsulation, je ne peux pas écrire en toute sécurité des fonctions sur ce type qui supposent que la fraction est réduite, car à l'avenir quelqu'un d'autre pourrait venir et ajouter un moyen de mettre la main sur une fraction non réduite.
Généralement, l'absence de ce type d'invariant peut conduire à:
- Algorithmes plus complexes car les conditions préalables doivent être vérifiées / assurées à plusieurs endroits
- Violations SÈCHES car ces conditions préalables répétées représentent la même connaissance sous-jacente (que l'invariant doit être vrai)
- Devoir appliquer des conditions préalables par des échecs d'exécution plutôt que des garanties au moment de la compilation
Donc ma question est quelle est la réponse de programmation fonctionnelle à ce genre d'invariant. Existe-t-il une manière fonctionnelle et idiomatique de réaliser plus ou moins la même chose? Ou y a-t-il un aspect de la programmation fonctionnelle qui rend les avantages moins pertinents?
PrimeNumber
classe. Il serait trop coûteux d'effectuer plusieurs vérifications redondantes de primalité pour chaque opération, mais ce n'est pas une sorte de test qui peut être effectué au moment de la compilation. (Beaucoup d'opérations que vous aimeriez effectuer sur des nombres premiers, par exemple la multiplication, ne forment pas une fermeture , c'est-à-dire que les résultats ne sont probablement pas garantis premiers. (Publication en tant que commentaires car je ne connais pas moi-même la programmation fonctionnelle.)