2016-08-21 4 views
0

Prenons fmap . const comme un exemple simple où j'essaie de comprendre ce qu'il fait:Bind variables de type dans une session GHCi

fmap :: Functor f => (a -> b) -> f a -> f b 
const :: a -> b -> a 

La chose poing que je remarque est que a, b sont ambigus lorsque je tente de comprendre fmap . const. L'utilisation de deux ou plusieurs signatures liées ensemble est ce que je veux dire par "GHCI session".

est ici par exemple de ce qui me aider à comprendre mieux les choses:

fmap :: Functor f => (a -> b) -> f a -> f b 
const :: c -> d -> c 
fmap . const :: Functor g => h -> g i -> g h 

se lient de Let g = f et réduis g:

fmap . const :: Functor f => h -> f i -> f h 

Pioche h :: h comme nom de variable moins de confusion pour la version pointful:

\h -> fmap (const h) :: Functor f => h -> f i -> f h 

Let's lier h = c et réduire h:

\c -> fmap (const c) :: Functor f => c -> f i -> f c 

Maintenant, il est beaucoup plus facile de voir que c en f c est venu de premier argument à const. Je vois également que i et a sont libres puisque je n'ai pas besoin de "fonctionner" sur eux.

Questions:

  • Y at-il un moyen d'empêcher les lettres d'être réutilisés dans une session GHCI?
  • Existe-t-il un moyen de lier et de réduire les variables de type dans une session GHCI? Finalement, je soupçonne qu'il existe un moyen plus facile de faire un processus de pensée équivalent.
+1

Vous ne pouvez pas contrôler les noms de tyvar choisis par le compilateur. "Lier et réduire" une variable de type n'a même pas de sens pour moi. ('a' et' b' ne sont pas ambigus dans 'fmap. const' car ils n'apparaissent pas du tout dans son type). Enfin, je ne suis pas sûr de ce que le processus de pensée est ici - il semble que vous demandez simplement GHCi pour le type d'une expression. – user2407038

+0

Si je comprends bien, vous rencontrez des problèmes avec le même type de noms de variables réutilisés dans différentes signatures? Différentes signatures ont des étendues différentes, de sorte que les variables de type sont complètement indépendantes les unes des autres. Lorsque vous construisez une expression en appliquant d'autres expressions, vous devrez peut-être effectuer une capture en évitant la substitution pour trouver le type correct (si vous cherchez cela), mais ceci est effectué automatiquement par GHCi (par exemple, ': t fmap. 'fera cela). Je ne suis pas sûr non plus de ce que vous entendez par «lier et réduire» dans ce contexte. –

+0

Peut-être une autre façon de résoudre ce problème serait de produire la preuve que le type ': t fmap.const' est en effet ce que GHCI prétend être donné les types de' fmap' et 'const'. – sevo

Répondre

0

Les variables de type dans les signatures sont en réalité liées par un quantificateur universel implicite. Il y a une extension du langage pour le rendre explicite, vérifiez que cette compile:

{-# LANGUAGE ExplicitForAll #-} 

fmapPrime :: forall a b f. Functor f => (a -> b) -> f a -> f b 
fmapPrime = fmap 

constPrime :: forall a b. a -> b -> a 
constPrime = const 

fmapConst :: forall a b f. Functor f => b -> f a -> f b 
fmapConst = fmap . const 

Donc, vous ne pouvez pas dire que les variables de type variables sont « réutilisés »: ils ne sont pas libres.