Подтвердить что ты не робот

Когда можно использовать IORef?

Одна вещь, которая меня всегда путала, - это то, хорошо ли использовать IORef. Существуют ли какие-либо рекомендации, которые следует соблюдать при принятии решения о том, следует ли использовать IORef для выполнения задачи? Когда самое подходящее время для использования государственной монады над IORef?

4b9b3361

Ответ 1

Состояние и его относительная ST также производят "монолитные" вычисления с учетом состояния, которые могут выполняться как единицы. Они в основном рассматривают изменчивое состояние как промежуточные данные, необходимые для получения результата, но не должны сами по себе представлять интерес для остальной части программы.

С другой стороны, то, что помещается внутри IORef, не является "вычислением", которое нужно запустить - это просто поле, содержащее простое значение, которое может быть использовано в IO довольно произвольно. Этот ящик может быть помещен внутри структур данных, передан вокруг (IO-части) программы, заменить его содержимое всякий раз, когда он удобен, быть закрытым функцией и т.д. На самом деле довольно много беспорядочного характера переменных и указатели на языки, такие как C, могут быть смоделированы с помощью IORefs, оказывая большую помощь любому эксперту-программисту C, желающему отстаивать свою репутацию в том, что он может писать код C на любом языке... Это то, что определенно нужно использовать с осторожностью.

Тем не менее, порой чрезвычайно громоздко, если не совершенно невозможно, изолировать все взаимодействия с куском изменчивого состояния в одном блоке кода - некоторые части состояния просто должны быть переданы, помещены внутри структур данных и т.д.. В таких случаях единственным вариантом может быть подход с коробкой. В качестве примера можно привести главу в которой описывается изменчивое состояние схемы Write Yourself в учебнике 48 часов (рекомендуется, кстати, рекомендуется). (См. Ссылку для приятного обсуждения того, почему наиболее целесообразно использовать IORefs, в отличие от State или ST, для моделирования среды Scheme в определенном дизайне интерпретатора Схемы.)

Короче говоря, эти среды должны быть вложены произвольными способами, поддерживаемыми между экземплярами взаимодействия с пользователем (a (define x 1), введенный в Scheme REPL, должен, по-видимому, приводить к тому, что пользователь может позже ввести x и вернуться 1 в качестве значения), поместить внутри объектов моделирование функций схемы (поскольку функции Scheme закрываются в средах, в которых они созданы) и т.д.

Подводя итог, я бы сказал, что если задача, похоже, полностью подходит для этого, государство будет стремиться обеспечить самое чистое решение. Если требуется несколько отдельных частей состояния, возможно, ST может помочь. Если, однако, вычисление с учетом состояния громоздко или невозможно заблокировать в своей части кода, состояние должно сохраняться в изменяемой форме на протяжении большей части жизни сложной программы и т.д., Тогда IORef могут быть просто соответствующая вещь.

И снова, если вам нужно какое-то изменчивое состояние, которое может быть передано и контролироваться с помощью кода ввода-вывода, то почему бы не проверить STM и его TVars! Они намного приятнее в присутствии concurrency, настолько, что фактически фактически упрощают решение некоторых связанных с w391 задач. На самом деле это не связано с вопросом, поэтому я буду сопротивляться, чтобы попытаться разработать.: -)

Ответ 2

Хм. Вы должны использовать IORef, когда вам нужно какое-то изменяемое состояние, но в одной среде с потоком. Или когда вы хотите изменить изменяемое поле внутри более крупной структуры, которая, в свою очередь, удерживается переменной синхронизации.

В общем, используйте MVars. У них более надежная семантика.

Ответ 3

Лично я бы сказал, что использовать IORef можно и только тогда, когда вы уже используете IO. В противном случае всегда State, если вам не нужна превосходная производительность ST. Можно использовать несколько потоков состояния с монадой State с несколькими вспомогательными функциями - вы просто делаете состояние кортежем или записью и определяете функции для установки, получения или обновления каждого поля отдельно.

В частности, обычно нет смысла использовать StateT s IO. Если вы уже находитесь в IO, у вас уже есть изменяемое состояние, поэтому вы можете использовать его, например, ReaderT (IORef s) IO.

Ответ 4

Я использую STRef, когда состояние локализовано и не требует взаимодействия со средой.