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

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

guard'ün Yanlış dalında, mzero'ün türü m a'dir, ancak guard'nın dönüş tipi m() olarak belirtilmiştir. Bu yüzden derleyici neden bu konuda şikayette bulunmayacağımı anlamıyorum.'m a' vs 'm()' bekçi

Eğer mzeroMaybe Int olarak yazılan bir değeri döndürürse, tabiki Maybe()'den farklıdır, değil mi?

cevap

6

m a, m()'un bir üst kümesi olduğundan derleyici şikayet etmeyecektir.

+0

'mzero', 'Belki Int' gibi bir şey döndürebilir, değil mi? Sanırım 'Belki()' – aXqd

+1

@ aXqd: Belki monad için, 'a' için tercih edilen bir türü olmayan mzero = Hiçbir şey. Eğer gerçekten 'Int' diye bir şey yapmıyorsanız, belki de() 'den farklıdır. Bununla birlikte, tür belki 'olası' için bir 'a', 'ınl' değil,' ınİ', yani belki de() 'geçerlidir. – kennytm

+0

@KennyTM Cevabınız için teşekkür ederiz. Evet, kötü bir örnek kullanabilirim. Ancak, özel bir yazı yazmam gerekirse - 'MyType', ve daha sonra bunu 'Monad' ve 'MonadPlus' örneğidir. O zaman 'mzero' iadesi 'MyType Int' yapabilirim. Aslında, eğer 'mzero' tarafından döndürülen şeyin 'm()' olmadığı bir şans varsa, derleyici bunun hakkında şikayette bulunmalı. Çünkü 'mzero' tipi ve 'bekçi' tipi dönüş tipi birbiriyle uyuşmuyor. Bu sonuca yanlış olduğumu biliyorum. Problemin nerede olduğundan emin değilim. : P – aXqd

0

mzero :: (MonadPlus m) => m a tipi forall (a :: *) (m :: * -> *). MonadPlus m => m a için kısa elin biraz mMonadPlus typeclass bir örneği olan bu sadece kısıtlama memnun olup olmadığını m ve mzero can, a yazın için tür kurucusu herhangi bir seçim anlamı olduğunu o tipte ol.

Benzer şekilde guard'un türü forall (m :: * -> *). MonadPlus m => Bool -> m()'dur. guard False = mzero'da, mzero'un sağ tarafındaki türü,'un uygun herhangi bir seçimi için m() olmalıdır.'u () ve m olmak üzere mzero 'un istediği tekil olarak seçerek,'un tam olarak ne olması gerektiği m() olur.

+0

Bu, "bekçi" türüydü. Şimdi 'guard :: Alternatif f => Bool -> f()' dir. Yeni türü yansıtan yeni bir cevap buluyorum. – dfeuer

+0

Düzenlemem ancak bir düzeltmedir. – dfeuer

İlgili konular