Правда ли, что порядок выполнения внутри блока 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

Если мы будем следовать строгой процедуре оценки, то вы увидите, что порядок действительно имеет значение. Но в ленивых условиях порядок утверждений не имеет значения. И, следовательно, вики утверждают, что "порядок утверждений не является критерием порядка оценки".

Другие вопросы по тегам