Im Gegensatz zu Maybe
ist Monad
kein Typ; es ist eine typeclass.
Das gleiche gilt für andere typeclasses:
Num :: * -> Constraint
Functor :: (* -> *) -> Constraint
Bifunctor :: (* -> * -> *) -> Constraint
Wo *
Betontypen (wie Bool
oder Int
) darstellt, ->
repräsentieren höhere kinded Typen (wie Maybe
) und Constraint
repräsentiert die Idee eine Typbeschränkung Aus diesem Grund:
Wie wir wissen, dass wir nicht eine Signatur wie diese machen kann:
return :: a -> Monad a -- This is nonsense!
Da Monad
sollte als Einschränkung verwendet werden, das heißt, ‚das sein muss eine Monade zur Arbeit ':
return :: (Monad m) => a -> m a
wir tun dies, weil wir, dass return
weiß nicht, auf jedem alten Typ m
arbeiten können, so dass wir de fein das Verhalten von return
für verschiedene Typen unter dem Namen Monad
. Mit anderen Worten, gibt es keine einzige Sache, die eine Monade genannt werden kann, sondern nur ein Verhalten, das Monadisch genannt werden kann.
Aus diesem Grund haben wir diese Typabhängigkeit erstellt und gesagt, dass wir etwas als Monade vordefiniert haben müssen, um diese Funktion zu verwenden. Deshalb ist die Art von Monad
(* -> *) -> Constraint
- es ist selbst kein Typ!
Maybe
ist eine Instanz Monad
. Dies bedeutet, dass irgendwo jemand geschrieben hat:
instance Monad Maybe where
(>>=) = ... -- etc
... und definiert, wie Maybe
als Monade verhalten soll. Aus diesem Grund können wir Maybe
mit Funktionen oder Typen verwenden, die die Präfix-Einschränkung Monad m => ...
haben. Dies ist im Wesentlichen, wo definiert man die Constraint von Monad
angewendet.