Правда ли, что порядок выполнения внутри блока do не зависит от порядка операторов?
Я читал https://wiki.haskell.org/Do_notation_considered_harmful и с удивлением прочитал следующие строки
Новички могут подумать, что порядок утверждений определяет порядок исполнения.... Порядок утверждений также не является критерием для порядка оценки.
В вики посте приведено несколько примеров, демонстрирующих это свойство. Хотя примеры имеют смысл, я все еще не до конца верю, что утверждение верно, так как если я напишу что-то вроде
main = do
putStrLn "foo"
putStrLn "bar"
putStrLn "baz"
Три строки выходят в порядке утверждений. Так что именно здесь происходит?
1 ответ
Это говорит о том, что порядок утверждений не влияет на критерии оценки. Как указывает @chi в IO, эффекты монады упорядочены по порядку, но порядок их оценки до сих пор не известен. Пример монады, которая прояснит концепцию:
test = do
x <- Just (2 + undefined)
y <- Nothing
return (x + y)
В ghci:
λ> test
Nothing
Код выше имеет три утверждения. Это может быть обезвожено в следующую форму:
Just (2 + undefined) >>= \x -> Nothing >>= \y -> return (x + y)
Сейчас с (>>=)
остается ассоциативным, он будет оцениваться так:
(Just (2 + undefined) >>= \x -> Nothing) >>= \y -> return (x + y)
Обратите внимание, что Maybe
монада определяется так:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
Nothing >>= _ = Nothing -- A failed computation returns Nothing
(Just x) >>= f = f x -- Applies function f to value x
Применение значения (2 + undefined)
к функции \x -> Nothing
приведет к Nothing
, Выражение 2 + undefined
не оценен, благодаря ленивой стратегии оценки, которой придерживается Haskell.
Теперь у нас есть уменьшенная форма:
Nothing >>= \y -> return (2 + undefined + y)
Глядя на Monad
Например, вы можете увидеть, что это будет производить Nothing
так как Nothing >>= _ = Nothing
, Что, если аргумент был строгим вместо этого:
test = do
!x <- Just (2 + undefined)
y <- Nothing
return (y + x)
Демо в ghci
:
λ> test
*** Exception: Prelude.undefined
Если мы будем следовать строгой процедуре оценки, то вы увидите, что порядок действительно имеет значение. Но в ленивых условиях порядок утверждений не имеет значения. И, следовательно, вики утверждают, что "порядок утверждений не является критерием порядка оценки".