2017-04-06 3 views
4

Lorsque je définis ces fonctions à l'intérieur ghci:liftM in ghci: pourquoi y a-t-il une telle différence?

> :m Control.Monad 
> let f n = n+1 
> let g = liftM f 

ils fonctionnent bien:

> g $ Just 2 
> Just 3 
> g $ [1,2] 
> [2,3] 

Mais quand je définis les mêmes fonctions dans le fichier (probl.hs):

import Control.Monad 

f :: Integer -> Integer 
f n = n + 2 

g = liftM f 

puis exécutez ce fichier via ghci:

ghci probl.hs 

J'ai obtenu ce message:

probl.hs:6:5: error: 
    * Ambiguous type variable `m0' arising from a use of `liftM' 
     prevents the constraint `(Monad m0)' from being solved. 
     Relevant bindings include 
     g :: m0 Integer -> m0 Integer (bound at probl.hs:6:1) 
... 
Failed, modules loaded: none. 

Pourquoi cette différence? Et comment résoudre le problème avec la deuxième situation (je veux le même comportement que dans le premier)?

+0

Je peux voir maintenant, cette réponse appartient au sujet de la restriction monomorphisme, mais point de question portait sur le comportement de ghci et liftM à l'intérieur. Je pense que c'est un peu différent. – Vladimir

Répondre

3

Vous êtes frappé par la restriction redoutable du Monomorphisme! C'est une règle non intuitive qui est désactivée dans GHCi, mais quand vous compilez. Utilisez une signature de type (recommandé) ou {-# LANGUAGE NoMonomorphismRestriction #-} pour le désactiver. Fondamentalement, il rend parfois les expressions sans signatures de type moins polymorphes que prévu.

Further reading