2010-11-20 11 views
2
guard :: (MonadPlus m) => Bool -> m() 
guard True = return() 
guard False = mzero 

Prelude Control.Monad> :t mzero 
mzero :: (MonadPlus m) => m a 

Im falschen Zweig der guard, ist die Art der mzerom a, aber der Rückgabetyp von guard wird als m() angegeben wurde. Daher verstehe ich nicht ganz, warum der Compiler sich darüber nicht beschweren wird.sind ein 'vs 'm()' in guard

Ich meine, wenn mzero gibt einen Wert als Maybe Int eingegeben, die natürlich anders ist als Maybe(), richtig?

Antwort

6

Der Compiler wird sich nicht beschweren, weil m a eine Obermenge von m() ist.

+0

'mzero' kann etwas wie 'Maybe Int' zurückgeben, oder? Ich denke es ist anders als 'Maybe()' – aXqd

+1

@aXqd: Für die Maybe Monade, 'mzero = Nothing', die keinen bevorzugten Typ für' a' hat. Wenn Sie tatsächlich 'Nothing' auf' Maybe Int' setzen, ist es anders als 'Maybe()'. Der Typ ist jedoch "Maybe a" für ein mögliches "a", nicht "Maybe Int", also ist "Maybe()" gültig. – kennytm

+0

@KennyTM Vielen Dank für Ihre Antwort. Ja, ich könnte ein schlechtes Beispiel verwenden. Wenn ich jedoch einen benutzerdefinierten Typ schreibe - "MyType", und mache es dann zur Instanz von "Monad" und "MonadPlus". Ich kann 'mzero' dann 'MyType Int' zurückgeben. In der Tat, ich denke, wenn es eine Chance gibt, dass das, was von 'mzero' zurückgegeben wird, nicht 'm()' ist, sollte der Compiler darüber klagen. Weil der Typ von 'mzero' und der Rückgabetyp von 'guard' nicht miteinander übereinstimmen. Ich weiß, dass ich bei dieser Schlussfolgerung falsch liege. Ich bin mir nur nicht sicher, wo das Problem liegt. : P – aXqd

0

Die Art der mzero :: (MonadPlus m) => m a ist ein bisschen kurz Hand für forall (a :: *) (m :: * -> *). MonadPlus m => m a, für von Typkonstruktor keine andere Wahl bedeutet m und geben a, wenn nur die Einschränkung, dass m eine Instanz der, mzero kann zufrieden MonadPlus typeclass ist sei bei diesem Typ.

Der Typ guard ist in ähnlicher Weise forall (m :: * -> *). MonadPlus m => Bool -> m(). In guard False = mzero muss der Typ der mzero auf der rechten Seite daher m() für jede geeignete Wahl von m sein. Wenn Sie a als () und m als angeforderte Monade wählen, wird der Typ mzerom(), was genau guard ist, muss zurückgegeben werden.

+0

Das war früher die Art von "Wächter". Jetzt heißt es 'guard :: Alternative f => Bool -> f()'. Ich denke, eine neue Antwort sollte den neuen Typ widerspiegeln. – dfeuer

+0

Meine Bearbeitung war jedoch nur eine Korrektur. – dfeuer