вы не можете избежать IO монады, как вы можете с другими монадами
Я не уверен, что вы подразумеваете под “ ” побега. Если вы имеете в виду, как-то разворачиваете внутреннее представление монадических значений (например, список -> последовательность cons-cells) –, что является детальностью реализации. Фактически, вы можете определить an IO
emulation in pure Haskell – в основном просто State
по многим доступным глобальным данным. Это имело бы всю семантику IO
, но без фактического взаимодействия с реальным миром, только имитация этого.
Если вы имеете в виду, вы можете “ значения экстракт ” внутри монады – Неа, это не вообще возможно, даже для самых чистых-Haskell монад. Например, вы не можете извлечь значение из Maybe a
(может быть Nothing
) или Reader b a
(что если b
необитаем?)
IO
действие может выполняться только с помощью функции main
Ну , в некотором смысле, все может управляться только функцией main
.Код, который каким-то образом не вызван с main
, будет сидеть там, вы можете заменить его undefined
, ничего не меняя.
IO всегда в нижней части цепи трансформаторов монады
Правда, но это также имеет место, например, дл ST
.
Реализация IO
монады неясна и исходный код показывает некоторые Haskell внутренности
Опять: реализация просто, хорошо, деталь реализации. Сложность реализаций IO
на самом деле имеет много общего с ее высокой оптимизацией; То же самое справедливо и для специализированных чистых монад (например, attoparsec).
As I already said), возможны гораздо более простые реализации, они просто не будут столь же полезны, как полноценный оптимизированный реальный тип IO
.
К счастью, внедрение не должно вас беспокоить; внутриIO
может быть неясным, но снаружи, фактический монадический интерфейс, довольно прост.
в чистом порядке оценки коды не имеет значения
Прежде всего заказ – оценки может вещества в чистом коде!
Prelude> take 10 $ foldr (\h t -> h `seq` (h:t)) [] [0..]
[0,1,2,3,4,5,6,7,8,9]
Prelude> take 10 $ foldr (\h t -> t `seq` (h:t)) [] [0..]
^CInterrupted.
Но на самом деле вы не можете получить неправильный, не- ⊥ результата благодаря misordered оценки чистого кода. Это фактически не применяется к переупорядочению монадических действий (IO
или иным образом), хотя, поскольку изменение порядка последовательности изменяет фактическую структуру результирующего действия, а не только порядок оценки, который среда выполнения будет использовать для , построить эту структуру.
Например (список монада):
Prelude> [1,2,3] >>= \e -> [10,20,30] >>= \z -> [e+z]
[11,21,31,12,22,32,13,23,33]
Prelude> [10,20,30] >>= \z -> [1,2,3] >>= \e -> [e+z]
[11,12,13,21,22,23,31,32,33]
Все, что сказал, конечно IO
является совершенно особенным, на самом деле я думаю, что некоторые люди стесняются называть его монады (это немного непонятно, что это на самом деле должно означать для IO
для выполнения законов монады). В частности, lazy IO является одним из самых серьезных нарушителей спокойствия (и лучше всего избегать, во все времена).
Когда я говорю «бегство» или «бег», я имею в виду функции запуска *, которые позволяют нам выполнять действия штата или читателя. Я думаю, что нет безопасной функции ввода-вывода. Было бы неплохо понять, почему – damluar
Не могли бы вы прояснить ** обновление **? – damluar
Эти 'run *' функции do _not_ "выполняют" что угодно. Они действительно просто раскрывают внутреннее представление. В случае с «IO» это не экспортируется официально (но, как я сказал дважды, существуют альтернативные реализации «IO», которые сводятся к простой государственной монаде). – leftaroundabout