State и его относительный ST оба производят "монолитные" вычисления с состоянием, которые могут выполняться как единицы. Они в основном рассматривают изменчивое состояние как промежуточные данные, которые необходимы для получения результата, но сами по себе не должны представлять интерес для остальной части программы.
С другой стороны, то, что помещается в IORef, - это не «вычисление», которое нужно запустить - это просто блок, содержащий простое значение, которое может быть использовано внутри IO довольно произвольным образом. Это поле может быть помещено в структуры данных, обведено (часть ввода-вывода) программы, заменено ее содержимое, когда это удобно, закрыто функцией и т. Д. На самом деле, довольно много беспорядочной природы переменных и указатели таких языков, как C, могут быть смоделированы с помощью IORefs, предоставляя большую помощь любому опытному программисту C, желающему поддержать свою репутацию способности писать код C на любом языке ... Это то, что определенно следует использовать с осторожностью. 1003 *
Тем не менее, иногда крайне громоздко, если не совершенно невозможно, изолировать все взаимодействия с фрагментом изменяемого состояния в одном блоке кода - некоторые части состояния просто необходимо обойти , помещать в структуры данных и т.д. В главе , посвященной изменчивому состоянию учебного пособия «Напиши себе схему за 48 часов» (кстати, очень рекомендуется), приводится пример. (См. Ссылку для хорошего обсуждения того, почему на самом деле наиболее целесообразно использовать IORef, а не State или ST, для моделирования сред Scheme в определенной конструкции интерпретатора Scheme.)
Короче говоря, эти среды должны быть вложены произвольным образом, поддерживаться между экземплярами взаимодействия с пользователем ((define x 1)
, напечатанный на схеме REPL, должен, вероятно, привести к тому, что пользователь позже сможет набрать x
и вернуться 1 в качестве значения), поместите внутрь объектов моделирование функций Scheme (поскольку функции Scheme близки по окружениям, в которых они созданы) и т. Д.
Подводя итог, я бы сказал, что если задача кажется вполне подходящей для нее, государство будет стремиться предоставить самое чистое решение. Если требуется несколько отдельных частей состояния, возможно, ST может помочь. Однако, если вычисление с состоянием является громоздким или невозможно заблокировать в своем собственном фрагменте кода, состояние должно сохраняться в изменяемой форме в течение большей части жизни сложной программы и т. Д., Тогда IORefs могут быть просто подходящая вещь.
Опять же, если вам нужно что-то вроде изменяемого состояния, которое может передаваться и взаимодействовать с ним посредством кода ввода-вывода, почему бы не проверить STM и его TVars! Они намного приятнее при наличии параллелизма, настолько, что фактически делают решение некоторых задач, связанных с параллелизмом, действительно простым. Это, правда, не имеет отношения к вопросу, поэтому я не буду настаивать на уточнении. : -)