我很困惑。我可以這樣寫:摺疊,功能組成,monads和懶惰,哦,我的?
import Control.Monad
main = print $ head $ (foldr (.) id [f, g]) [3]
where f = (1:)
g = undefined
和輸出是1
。這是有道理的,因爲它簡化爲:
main = print $ head $ ((1:) . undefined . id) [3]
main = print $ head $ (1:) ((undefined . id) [3])
main = print $ head $ 1 : ((undefined . id) [3])
main = print $ 1
但是,如果我用一個模糊的類似單子的技術,這是行不通的一樣:
import Control.Monad
main = print $ (foldr (<=<) return [f, g]) 3
where f = const Nothing
g = undefined
這擊中prelude.Undefined
。這是奇怪的,因爲我希望它減少:
main = print $ ((const Nothing) <=< undefined <=< return) 3
main = print $ return 3 >>= undefined >>= (\_ -> Nothing)
main = print $ Nothing -- nope! instead, undefined makes this blow up
然而,翻轉的組成順序:
import Control.Monad
main = print $ (foldr (>=>) return [f, g]) 3
where f = const Nothing
g = undefined
沒有完成預期短路併產生Nothing
。
main = print $ (const Nothing >=> undefined >=> return) 3
main = print $ (const Nothing 3) >>= undefined >>= return
main = print $ Nothing >>= undefined >>= return
main = print $ Nothing
我想比較這兩種方法可能是比較蘋果和橙子,但你能解釋一下這個區別嗎?我認爲f <=< g
是的一元類似物,但它們顯然不像我想象的那麼相似。你能解釋爲什麼嗎?