2010-11-20 14 views
2
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() '

mzeroMaybe Intとタイプされた値を返した場合、Maybe()とは違います

答えて

6

m am()のスーパーセットであるため、コンパイラは不平を言うことはありません。

+0

'mzero'は 'Maybe Int'のようなものを返すことができます。私はそれが 'Maybe()'とは違うと思う。 – aXqd

+1

@aXqd:Maybeモナドの場合、 'mzero = Nothing'は' a'に優先する型を持たない。もしあなたが本当に 'Nothing'を' Maybe Int'にキャストしたら、それは 'Maybe()'と違っています。しかし、 'Maybe()'は有効ではないので、 'Maybe a'ではなく' Maybe a'の型が 'Maybe a'です。 – kennytm

+0

@KennyTMご返信ありがとうございます。はい、私は悪い例を使用するかもしれません。しかし、私はカスタムタイプ - 'MyType'を書いて、それを 'Monad'と 'MonadPlus'のインスタンスにします。私は 'mzero'に 'MyType Int'を返します。実際、 'mzero'によって返されるものが 'm()'ではない可能性がある場合、コンパイラはそれに不満を持ちます。 'mzero'の型と 'guard'の戻り型が一致しないためです。私はこの結論に間違っていることを知っています。問題がどこにあるのか分かりません。 :P – aXqd

0

mMonadPlus型クラスのインスタンスであることを単に制限が満たされた場合mzero :: (MonadPlus m) => m aのタイプは、ための任意選択型コンストラクタm及びタイプaを意味し、forall (a :: *) (m :: * -> *). MonadPlus m => m aための短い手のビットであり、mzero CANそのタイプであること。

guardのタイプは、同様に、forall (m :: * -> *). MonadPlus m => Bool -> m()です。 guard False = mzeroでは、右辺のmzeroのタイプは、mの任意の適切な選択のためにm()でなければなりません。 a()mを要求モナドとすると、mzeroの型自体はm()になります。正確にはguardが返す必要があります。

+0

以前は「ガード」のタイプでした。今度は 'guard :: Alternative f => Bool-> f()'です。私は新しい答えが新しいタイプを反映すべきだと考えます。 – dfeuer

+0

しかし、私の編集は訂正だけでした。 – dfeuer

関連する問題