Складывание, составление функций, монады и лень, о боже

Я озадачен. Я могу написать это:

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, но они, видимо, не так похожи, как я думал. Вы можете объяснить, почему?

Ответы на вопрос(2)

Ваш ответ на вопрос