我感到困惑。我可以写出以下代码:
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
是单子范畴对应于f.g
的模拟,但它们显然不像我想象的那么相似。 你能解释一下为什么吗?