Tôi đang bối rối. Tôi có thể viết điều này:Folding, thành phần chức năng, monads, và laziness, oh my?
import Control.Monad
main = print $ head $ (foldr (.) id [f, g]) [3]
where f = (1:)
g = undefined
và đầu ra là 1
. Có ý nghĩa, vì nó làm giảm tới:
main = print $ head $ ((1:) . undefined . id) [3]
main = print $ head $ (1:) ((undefined . id) [3])
main = print $ head $ 1 : ((undefined . id) [3])
main = print $ 1
Nhưng nếu tôi sử dụng một kỹ thuật monadic mơ hồ tương tự, nó không hoạt động giống nhau:
import Control.Monad
main = print $ (foldr (<=<) return [f, g]) 3
where f = const Nothing
g = undefined
này chạm prelude.Undefined
. Đó là kỳ quặc, bởi vì tôi mong chờ nó giảm:
main = print $ ((const Nothing) <=< undefined <=< return) 3
main = print $ return 3 >>= undefined >>= (\_ -> Nothing)
main = print $ Nothing -- nope! instead, undefined makes this blow up
Tuy nhiên, lật thứ tự của phần:
import Control.Monad
main = print $ (foldr (>=>) return [f, g]) 3
where f = const Nothing
g = undefined
không hoàn thành dự kiến ngắn mạch và tạo ra Nothing
.
main = print $ (const Nothing >=> undefined >=> return) 3
main = print $ (const Nothing 3) >>= undefined >>= return
main = print $ Nothing >>= undefined >>= return
main = print $ Nothing
Tôi cho rằng so sánh hai phương pháp có thể đã so sánh táo và cam, nhưng bạn có thể giải thích sự khác biệt không? Tôi nghĩ rằng f <=< g
là tương tự monadic để f . g
, nhưng họ dường như không giống như tôi nghĩ. Bạn có thể giải thích lý do tại sao?