guard :: (MonadPlus m) => Bool -> m()
guard True = return()
guard False = mzero
Prelude Control.Monad> :t mzero
mzero :: (MonadPlus m) => m a
guard
のFalse分岐では、mzero
の型はm a
ですが、guard
の戻り型はm()
として指定されています。それで、私はコンパイラがこれについて不平を言ってくれない理由をそれほど得られません。'm a'とガード中のm() '
mzero
がMaybe Int
とタイプされた値を返した場合、Maybe()
とは違います
'mzero'は 'Maybe Int'のようなものを返すことができます。私はそれが 'Maybe()'とは違うと思う。 – aXqd
@aXqd:Maybeモナドの場合、 'mzero = Nothing'は' a'に優先する型を持たない。もしあなたが本当に 'Nothing'を' Maybe Int'にキャストしたら、それは 'Maybe()'と違っています。しかし、 'Maybe()'は有効ではないので、 'Maybe a'ではなく' Maybe a'の型が 'Maybe a'です。 – kennytm
@KennyTMご返信ありがとうございます。はい、私は悪い例を使用するかもしれません。しかし、私はカスタムタイプ - 'MyType'を書いて、それを 'Monad'と 'MonadPlus'のインスタンスにします。私は 'mzero'に 'MyType Int'を返します。実際、 'mzero'によって返されるものが 'm()'ではない可能性がある場合、コンパイラはそれに不満を持ちます。 'mzero'の型と 'guard'の戻り型が一致しないためです。私はこの結論に間違っていることを知っています。問題がどこにあるのか分かりません。 :P – aXqd