Birkaç ek açıklamalar, Reid Barton's general answer ve somut soru daha açık arasındaki bağlantıyı yapmak için. Bu durumda
, gerçekten
join
açısından sizin
Monad
örneğini çalışmak için işe yarar:
join' :: m (n (m (n b))) -> m (n b)
join' = fmap join . join . fmap sequence
uygun yerlere compose
/getCompose
reintroducing ve m >>= f = join (fmap f m)
kullanarak, bu gerçekten olduğunu doğrulayabilir Tanımınıza eşdeğerdir (prebind
'un bu denklemde fmap f
olduğunu unutmayın).
Bu tanım
rahat şemalar ile yasaları doğrulamak mümkün kılar.
MT id MT id MT id MT
----> ----> ---->
rT2 | | rT1 | | rT1 | | id
rM3 V V rM3 V V V V
----> ----> ---->
MTMT sM2 MMTT jM2 MTT jT0 MT
genel dikdörtgen monad yasası: Burada join . return = id
yani (fmap join . join . fmap sequence) . (return . return) = id
için biridir
M id M
---->
rM1 | | id
V V
---->
MM jM0 M
mutlaka kareler arasında her iki yönde aynı parçalar yok sayarak, gördüğümüz iki sağdaki o aynı yasaya kareler tutar. (Tabii ki, bu "kareler" ve "dikdörtgenler" diye adlandırmak biraz saçma, ama sahip oldukları tüm id
yanları göz önüne alındığında, sınırlı ASCII sanat becerilerime daha iyi uyuyor.) Ilk kare olsa da, ... Reid Barton bahseder Vikipedi sayfasında sağ alt diyagramıdır sequence . return = fmap return
e
M id M
---->
rT1 | | rT0
V V
---->
TM sM1 MT
tutarlar ... ve daha o tuttuğunu öne süren verildiği gibi Reid Barton ait olmayan cevap gösterir. Biz join . fmap return = id
yasaya aynı stratejiyi uygularsanız
, sağ üst diyagram, sequence . fmap return = return
, gelirse - ki (derhal sonucu) sadece olduğu gibi, ancak, kendi başına bir sorun olmadığını Traversable
kimlik yasası. Son olarak, join . fmap join = join . join
kanunu ile aynı şeyi yapmak diğer iki diyagramı yapar - sequence . fmap join = join . fmap sequence . sequence
ve sequence . join = join . sequence . fmap sequence
- bahar ileriye.
Dipnotlar: steno için
- Açıklama:
r
return
olduğunu s
sequence
ve j
olduğunu join
olduğunu. Fonksiyon kısaltmalarından sonra gelen büyük harfler ve sayılar, ilgili monadı ve 'un sokulmuş veya değiştirilmiş katmanını - s
'da sona erdirir, yani başlangıçta başlangıçtaki iç katmanı ifade eder. dış katmanın her zaman bir T
olduğunu biliyoruz. Katmanlar sıfırdan başlayarak aşağıdan yukarıya doğru numaralandırılır. Kompozisyon, birinci fonksiyonun altındaki ikinci fonksiyon için kısayol yazılarak gösterilir.
[Burada] (http://www.math.mcgill.ca/barr/papers/ttt.pdf), bu konuyu kategori teorisi açısından ele alan harika bir kitaptır (özellikle, p257 "Dağıtım Yasalar ") ve * göreceli olarak * (kategori teorisini bilen birinin bakış açısından ...)" M "için gerekli koşulun basit bir kanıtını verir. 'M' ve 'N' monadlar ise bir monad olacak. [Burada] (http://stackoverflow.com/questions/29453915/composing-monads-v-applicative-functors) verdiğiniz kod üzerinde ufak bir farklılık gösteren başka bir sorudur - belki de daha yararlı bir başlangıç noktası olacaktır . – user2407038
Spoiler: öyle. – user2407038
Lol, teşekkürler! O kadar uzun bir süre önce o mesajı okumamıştım, ancak bu yanıtı [bu yorumu] (http://stackoverflow.com/questions/29453915/composing-monads-v-applicative-functors#comment47075703_29454112) yanıtlayarak olumlu bir cevap verdi. –