Чтобы добавить функции ввода-вывода в интерпретатор языка программирования, написанный на Haskell, у меня есть два варианта:
- Измените весь интерпретатор, чтобы он работал внутри монады IO.
- В функциях среды выполнения, которые могут вызываться интерпретируемыми программами, используется
unsafePerformIO
.
Первое кажется мне плохой идеей — это фактически сводит на нет любые преимущества чистоты, поскольку IO
охват практически везде в программе. Я также в настоящее время активно использую ST
, и мне пришлось бы изменить большое количество программы, чтобы добиться этого, так как я не вижу возможности использовать одновременно ST
и IO
(?).
Последнее меня нервирует — как следует из названия функции, это небезопасно, но я думаю, что в данной ситуации это может быть оправдано. Особенно:
- Объем кода, затронутого этим изменением, будет очень небольшим.
- Точки, в которых может выполняться ввод-вывод, уже явно упорядочены с помощью использования
seq
в контрольных точках во время оценки интерпретируемых выражений. - Возможно, что более важно, значения, возвращаемые действиями ввода-вывода, будут использоваться только в интерпретируемых разделах кода, где я могу гарантировать ссылочную прозрачность благодаря тому факту, что интерпретатор не может быть вызван несколько раз с одними и теми же аргументами, так как счетчик операций будет проходить через поток. всю систему как часть одного и того же изменения и всегда передается с уникальным значением каждой функции, которая будет использовать
unsafePerformIO
.
В этом случае есть ли веская причина не использовать unsafePerformIO
?
Обновлять
Меня спросили, почему я хочу сохранить чистоту в переводчике. На это есть ряд причин, но, пожалуй, самая насущная заключается в том, что я намереваюсь позже создать компилятор для этого языка, и этот язык будет включать в себя множество методов метапрограммирования, которые потребуют, чтобы компилятор включал интерпретатор, но я хочу быть способны гарантировать чистоту результатов компиляции. Для этой цели в языке будет чистое подмножество, и я хотел бы, чтобы интерпретатор был чистым при выполнении этого подмножества.
IO
значениями в представлении вашего интерпретируемого языка? - person Random Dev   schedule 25.06.2016seq
в нужных местах может быть менее тривиальным, чем кажется. Далее -- не могли бы вы написать фиктивный тип для интерпретатора? Этоint :: Program -> Result
или что-то подобное? - person chi   schedule 25.06.2016Scope s -> Expr -> ST s (Either ErrorMessage Value)
, гдеScope s
содержит описание как глобальных (изменяемых) переменных, так и функций/классов, определенных в программе, аExpr
в основном представляет собой простое выражение начальной загрузки, которое вызывает функцию в программе. - person Jules   schedule 25.06.2016