Es leitet die benötigten Typen.
Aus der Bedeutung einer instance
Definition ist klar, dass wir
returnMaybeT :: Monad m => a -> MaybeT m a
returnMaybeT x = MaybeT (return (return x))
Da MaybeT :: m (Maybe a) -> MaybeT a
(genommen als Funktion) wissen wir, dass der innere Stapel von return
s zu definieren sind versucht Typ
haben muss
return (return x) :: Monad m => a -> m (Maybe a)
Jetzt wissen wir, dass return
ist eine polymorphe Funktion, die einen Typ wie
hat 10
für beliebigMonad
n
. Im Fall von dieser ersten return
, die Monad m =>
Constraint sagt uns, dass m
ist ein Monad
und so können wir seine Definition von Rückkehr verwenden. Auf diese Weise können wir den ganzen Weg hinunter zum inneren return
return x :: a -> Maybe a
und da wir wissen, dass Maybe
eine Monad
Instanz hat können wir die return
davon verwenden.
Letztlich alle der Compiler zu tun hat, ist whittle seinen Weg durch den Ausdruck versucht, die Typen in jeder return
erforderlich, um zu bestimmen. Nachdem der benötigte Typ ermittelt wurde, muss er prüfen, ob er eine Monad
Instanz für diesen Typ kennt. Dies ist einfach für Maybe
, da es Beton ist, aber ein wenig schwieriger für m
zu sehen, da es nur eine Variable ist.
Der Grund m
funktioniert, weil wir die Variable gezwungen haben sicherlich einige Typ zu sein, die Monad
instanziiert.
Sollte nicht die erste Zeile in der letzten Zeile vom Typ "Maybe a -> m (Vielleicht a)" oder der allgemeinere "b -> m b" mit "b ~ Maybe a" sein? – Laar
@Laar Technisch ja, aber es ist leichter (und moralisch äquivalent), es so zu behandeln. – jozefg