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