2016-06-23 5 views
2

J'ai également essayé ce qui suit avec l'extension LiberalTypeSynonyms comme suggéré dans When (if ever) can type synonyms be partially applied?, et j'ai ajouté une définition de type explicite à f dans la définition de Id. J'ai toujours la même erreur. Je ne sais pas s'il y a d'autres extensions qui pourraient aider.Pourquoi ne peut-on pas appliquer partiellement Id a = a aux données D f = D (f())?

ghci> type Id a = a 
ghci> type Const a b = a 
ghci> data D f = D (f()) 
ghci> (((() :: Id()) ::()) :: Const() a) 
() 
ghci> D() :: D Id 

<interactive>:10:9: 
    Type synonym ‘Id’ should have 1 argument, but has been given none 
    In an expression type signature: D Id 
    In the expression: D() :: D Id 
    In an equation for ‘it’: it = D() :: D Id 

Cela me rend vraiment confus. f dans D est * -> * et Id est * -> *. Qu'y a-t-il de plus à cela?

+1

Les synonymes de type partiellement appliqués sont essentiellement équivalents aux lambdas de type niveau, ce qui rend l'algorithme de contrôle de type beaucoup plus complexe. GHC ne les autorise pas. Utilisez à la place les wrappers 'newtype's ou' data's et enveloppez/déroulez vos valeurs avec un constructeur si nécessaire. Sinon, passez à Agda ou Coq :-P – chi

+2

En passant, la règle des synonymes de type libéral ne vous donne pas beaucoup plus de flexibilité, seulement un peu. Si après l'expansion de tous les types-synonymes, nous en avons encore partiellement appliqués, une erreur de type est déclenchée. Si vous aviez le type D f = f() 'à la place, l'extension autoriserait votre code. Mais 'D f' serait du même type que' f() '. – chi

+0

@chi qui clarifie l'extension pour moi. Malheureusement, dans mon problème particulier, je ne peux pas avoir D comme un synonyme de type, mais je pourrais gérer avec Id et Const être newtypes. Votre commentaire "c'est trop complexe pour GHC" se qualifie comme une réponse. Je pourrais l'accepter si vous le postez comme ça, mais peut-être que je devrais attendre un peu plus, au cas où quelqu'un d'autre voudrait poster aussi. – JoL

Répondre

4

Le système de type Haskell ne prend pas en charge les familles ou les familles de types partiellement appliqués (également connus sous le nom de non saturé). Cependant, les types data et newtypes prennent en charge une application partielle.

newtype D f = D (f()) 
newtype Id a = Id a 

d :: D Id 
d = D (Id()) 

newtype s sont effacées lors de la compilation, de sorte que le seul coût que vous payez est un syntaxique.

+2

Sauf quand ce n'est pas :(Ed Kmett veut ajouter 'liftCoercion :: Maybe (Coercion ab -> Coercition (fa) (fb))' à la classe 'Functor', et des méthodes similaires à' Contravariant', 'Bifunctor' et 'Profunctor', pour rendre les coercitions plus généralement applicables et donc plus de nouveaux types libres. – dfeuer