Jestem zdziwiony. Mogę napisać to:Składanie, skład funkcji, monady i lenistwo, o mój?
import Control.Monad
main = print $ head $ (foldr (.) id [f, g]) [3]
where f = (1:)
g = undefined
, a wyjście to 1
. Ma to sens, ponieważ zmniejsza się:
main = print $ head $ ((1:) . undefined . id) [3]
main = print $ head $ (1:) ((undefined . id) [3])
main = print $ head $ 1 : ((undefined . id) [3])
main = print $ 1
Ale jeśli mogę użyć niejasno podobną technikę jednowartościowy, nie działają tak samo:
import Control.Monad
main = print $ (foldr (<=<) return [f, g]) 3
where f = const Nothing
g = undefined
To uderza prelude.Undefined
. Co jest dziwne, bo bym się spodziewał, że w celu zmniejszenia:
main = print $ ((const Nothing) <=< undefined <=< return) 3
main = print $ return 3 >>= undefined >>= (\_ -> Nothing)
main = print $ Nothing -- nope! instead, undefined makes this blow up
Jednak odwracanie kolejności składzie:
import Control.Monad
main = print $ (foldr (>=>) return [f, g]) 3
where f = const Nothing
g = undefined
ma osiągnąć oczekiwany zwarcia i produkuje Nothing
.
main = print $ (const Nothing >=> undefined >=> return) 3
main = print $ (const Nothing 3) >>= undefined >>= return
main = print $ Nothing >>= undefined >>= return
main = print $ Nothing
Przypuszczam, że porównanie tych dwóch podejść mogły być porównywanie jabłek i pomarańczy, ale można wyjaśnić różnicę? Myślałem, że f <=< g
był monadycznym analogiem do f . g
, ale najwyraźniej nie są one analogiczne, jak myślałem. Czy możesz mi wytłumaczyć dlaczego?