En utilisant les dépendances fonctionnelles, j'appuie fréquemment sur Condition de couverture. Il est possible de le soulever avec UndecidableInstances
, mais j'essaie généralement de rester loin de cette extension.Comment contourner la condition de couverture pour les dépendances fonctionnelles sans utiliser -XUndecidableInstances
Voici un exemple un peu artificiel, qui fonctionne sans UndecidableInstances
:
{-# Language MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
data Result = Result String
deriving (Eq, Show)
data Arguments a b = Arguments a b
class Applyable a b | a -> b where
apply :: a -> b -> Result
instance Applyable (Arguments a b) (a -> b -> Result) where
(Arguments a b) `apply` f = f a b
Quand je fais plus générique le type de résultat, la condition couverture échoue (donc nécessitant UndecidableInstances
):
{-# Language MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, UndecidableInstances #-}
data Result a = Result a
deriving (Eq, Show)
data Arguments a b = Arguments a b
class Applyable a b c | a -> b c where
apply :: a -> b -> Result c
instance Applyable (Arguments a b) (a -> b -> Result c) c where
(Arguments a b) `apply` f = f a b
I pensé que parce que b
et c
sont tous deux déterminés par a
, le code plus générique ne devrait pas causer de problèmes, alors mes questions:
- Existe-t-il des problèmes possibles avec l'aide
UndecidableInstances
ici - Puis-je modéliser le scénario ci-dessus sans compter sur
UndecidableInstances
(peut-être des familles de type?)
Il n'y a pas de raison de rester loin de 'UndecidableInstances'. Le pire qui puisse arriver est que le vérificateur de type commence à boucler (et vous en parle, je pense). Vous pouvez rendre la condition de couverture de plus en plus intelligente, mais elle ne fera jamais tout ce que vous pourriez désirer, car c'est indécidable. – augustss
comment est-ce que c est déterminé par un ici? – Saizan