หากเราเปรียบเทียบประเภทต่างๆ
(<*>) :: Applicative a => a (s -> t) -> a s -> a t
(>>=) :: Monad m => m s -> (s -> m t) -> m t
เราได้เบาะแสว่าอะไรที่แยกแนวคิดทั้งสองออกจากกัน ว่า(s -> m t)
ในรูปแบบของการ(>>=)
แสดงให้เห็นว่าค่าในสามารถตรวจสอบพฤติกรรมของการคำนวณในs
m t
Monads อนุญาตให้มีการรบกวนระหว่างชั้นค่าและการคำนวณ ตัว(<*>)
ดำเนินการไม่อนุญาตให้มีการรบกวนดังกล่าว: ฟังก์ชันและการคำนวณอาร์กิวเมนต์ไม่ได้ขึ้นอยู่กับค่า นี่มันกัดจริงๆ เปรียบเทียบ
miffy :: Monad m => m Bool -> m x -> m x -> m x
miffy mb mt mf = do
b <- mb
if b then mt else mf
ซึ่งใช้ผลลัพธ์ของเอฟเฟกต์บางอย่างในการตัดสินใจระหว่างการคำนวณสองครั้ง(เช่นการยิงขีปนาวุธและการลงนามในการสงบศึก) ในขณะที่
iffy :: Applicative a => a Bool -> a x -> a x -> a x
iffy ab at af = pure cond <*> ab <*> at <*> af where
cond b t f = if b then t else f
ซึ่งใช้ค่าของab
การเลือกระหว่างค่าของการคำนวณสองค่าat
และaf
การดำเนินการทั้งสองอย่างอาจส่งผลที่น่าเศร้า
เวอร์ชัน monadic นั้นอาศัยพลังพิเศษใน(>>=)
การเลือกการคำนวณจากค่าเป็นหลักและนั่นอาจมีความสำคัญ อย่างไรก็ตามการสนับสนุนพลังดังกล่าวทำให้ monads ยากที่จะแต่ง ถ้าเราพยายามสร้าง 'ผูกสองครั้ง'
(>>>>==) :: (Monad m, Monad n) => m (n s) -> (s -> m (n t)) -> m (n t)
mns >>>>== f = mns >>-{-m-} \ ns -> let nmnt = ns >>= (return . f) in ???
เรามาไกลขนาดนี้ แต่ตอนนี้เลเยอร์ของเราทั้งหมดพังทลาย เรามีดังนั้นเราจึงจำเป็นที่จะกำจัดของนอกn (m (n t))
n
ดังที่ Alexandre C กล่าวว่าเราสามารถทำได้ถ้าเรามีความเหมาะสม
swap :: n (m t) -> m (n t)
เพื่อเปลี่ยนรูปn
เข้ามาและก็ไปที่อื่น ๆjoin
n
'ใช้สองครั้ง' ที่อ่อนแอกว่าจะกำหนดได้ง่ายกว่ามาก
(<<**>>) :: (Applicative a, Applicative b) => a (b (s -> t)) -> a (b s) -> a (b t)
abf <<**>> abs = pure (<*>) <*> abf <*> abs
เนื่องจากไม่มีการรบกวนระหว่างเลเยอร์
ในทำนองเดียวกันมันเป็นการดีที่จะรับรู้เมื่อคุณต้องการพลังพิเศษของMonad
s และเมื่อไหร่ที่คุณสามารถหลีกหนีจากโครงสร้างการคำนวณที่แข็งแกร่งที่Applicative
รองรับได้
โปรดทราบว่าแม้ว่าการแต่งเพลงจะยาก แต่ก็อาจมากกว่าที่คุณต้องการ ประเภทm (n v)
ระบุการคำนวณด้วยm
-effects จากนั้นคำนวณด้วยn
-effects ถึง a -value v
โดยที่m
-effects จะเสร็จสิ้นก่อนที่n
-effects จะเริ่มต้น (ดังนั้นจึงจำเป็นสำหรับswap
) หากคุณเพียงแค่ต้องการแทรก - เอฟm
เฟกต์กับเอฟn
เฟกต์องค์ประกอบก็อาจจะมากเกินไปที่จะถาม!