Ответ 1
Нет, вы по-прежнему получаете те же проблемы, вызванные командой seq
, поскольку любая монада, используемая в первом аргументе evaluate
, будет иметь свои правила монады. Исходя из этого правила в ertes ответ:
В категории Клейсли монада порождает
return
- это морфизм идентичности и(<=<)
- это композиция. Итак,return
должно быть для(<=<)
:return <=< x = x
Это означает, что вы можете заменить return <=< x
на x
на любую действительную монаду, не изменяя работу программы.
Используя это с помощью функции evaluate
...
evaluate (return <=< undefined :: a -> Identity b) >> putStrLn "hello"
выводит привет. Используя то, что должно быть эквивалентным выражением, заменив return <=< undefined
на undefined
:
evaluate (undefined :: a -> Identity b) >> putStrLn "hello"
вместо этого вызывает исключение Prelude.undefined
.
Это происходит только с функцией оценки. Обратите внимание, что return
имеет точно такую же подпись типа evaluate
. Если вы замените evaluate
на return
в приведенных выше командах, результирующее действие для обеих команд будет одинаковым (они выводят hello
).