вот немного пищи для размышлений.
Когда я пишу монадический код, монада накладывает порядок на выполненные операции. Например, если я пишу в монаде IO:
do a <- doSomething
b <- doSomethingElse
return (a + b)
Я знаю, что doSomething
будет выполняться до doSomethingElse
.
Теперь рассмотрим эквивалентный код на языке C:
return (doSomething() + doSomethingElse());
Семантика C на самом деле не определяет, какой порядок эти два вызова функций будут оцениваться, поэтому компилятор может свободно перемещать вещи по своему усмотрению.
Мой вопрос таков: Как я могу написать монадический код в Haskell, который также оставляет этот порядок оценки undefined? В идеале я бы воспользовался некоторыми преимуществами, когда мой оптимизатор компилятора просматривает код и запускает перемещение вещей.
Вот некоторые возможные методы, которые не выполняют задание, но находятся в правильном "духе":
- Напишите код в стиле функториальности, т.е. напишите
plus doSomething doSomethingElse
иplus
запишите монадические вызовы. Недостатки: вы теряете общий доступ к результатам монадических действий, аplus
все еще принимает решение о том, когда все оценивается. - Используйте ленивый IO, т.е.
unsafeInterleaveIO
, который откладывает планирование к требованиям, ленивым для оценки. Но ленивый отличается от строгого порядка undefined: в частности, я хочу, чтобы все мои монадические действия выполнялись. - Lazy IO, в сочетании с немедленным ответом на все аргументы. В частности,
seq
не налагает ограничений порядка.
В этом смысле я хочу нечто более гибкое, чем монадическое упорядочение, но менее гибкое, чем полная ленивость.