Как показанный в этом ответе, seq
в сочетании с undefined
делает очень странные вещи, когда дело доходит до эквациональных рассуждений, например, оно может сделать любую монаду неудачной, Другой пример - этот вопрос.
Недавно я наткнулся на evaluate :: a -> IO a
, который делает аналогичную вещь - он оценивает свой аргумент WHNF, но только когда действие IO
оценивается. Это кажется гораздо более безопасным, так как мы ожидаем, что "в IO
мы сможем сделать все". Конечно, его нельзя использовать повсеместно, но часто необходимость оценивать выражение каким-то образом связана с операцией IO
(например, заставить рабочий поток оценивать вычисление вместо потребляющего потока при работе с MVar
s).
Итак, я хотел бы спросить, насколько безопасно evaluate
? Можно ли создавать примеры (конечно, IO
), где он нарушает рассуждения о коде вроде seq
? Или я могу считать его безопасной заменой seq
(если это возможно для конкретной программы)?