2016-07-10 28 views
3

Dies ist die Art von >>=:Mit Rückkehr in Haskell bindet Operator (>> =)

(>>=) :: Monad m => m a -> (a -> m b) -> m b 

Es braucht eine Funktion als zweites Argument.

Und hier ist die Art der return:

return :: Monad m => a -> m a 

Returns m a

Und dies offensichtlich Kontrollen geben:

(>>) :: Monad m => m a -> m b -> m b 
x >> y = x >>= (\_ -> y) 

Aber warum tut die folgende Typprüfung und funktionieren ähnlich wie die über Code?

(>>) :: Monad m => m a -> m b -> m b 
x >> y = x >>= return y 

Hier return y soll m a als Typ und nicht a -> m a. Warum funktioniert es?

+0

'Return' ist' const' für Funktionen – Bergi

Antwort

5

Sie mischen hier tatsächlich zwei verschiedene Monaden, das ist was passiert. x >>= return y ist in diesem Fall zu vereinheitlichenden

(>>) :: ∀ m a b . Monad m => m a -> m b -> m b 
x >> y = x >>= (return :: m b -> a -> m b) y 
     -- aka return :: (m b) -> (a->) (m b) 

wo die return in der Monad (a->) Instanz implementiert:

instance Monad (->) a where 
    return x = \_ -> x 
    ... 

Es hat nichts mit der Monad m Instanz zu tun.

Was warum diese return in der Funktion Monade arbeitet: return :: m b -> a -> m b aus der Umgebung zu entnehmen, bevor der Compiler jemals Grund zu typeclass Instanzen starten. Nun hat der Typ m b -> a -> m b, d. H. m b -> (a->m b), die Form mb -> amb. Die Signatur return :: Monad μ => α -> μ α bewirkt daher, dass der Compiler mit μ α ~ amb ~ a->m b übereinstimmt. Nur an diesem Punkt wird der Compiler tatsächlich die Monaden-Instanz für return wählen, und zwar durch Beobachten, dass tatsächlich die Form μ α hat, mit μ ~ (a->) und α ~ m b. Daher muss es die (a->) Monade sein.

+0

Danke, ich glaube, ich verstehe, warum es Typchecks gegeben, dass es die 'Monad (->) a'-Instanz verwendet. Was ich immer noch nicht verstehe ist, wie hat es 'Monad (->) a' gewählt? Was war die Logik dahinter? War es einfach, dass es buchstäblich die einzige Instanz war, deren "Rückkehr" eine Art Scheck geben würde? –

4

Es gibt eine Monad-Instanz für Funktionen und return ist return x = \_ -> x (oder äquivalent return = const).

Also, wenn Sie return y tun, wo eine Funktion erwartet wird, wählt es einfach die return der Funktion Monad.