2016-04-13 2 views
1

После погружения в монады я понимаю, что они представляют собой общую концепцию, позволяющую проводить вычисления цепочки внутри некоторого контекста (неудача, недетерминированность, состояние и т. Д.), И за ними нет волшебства.В каком смысле IO monad special (если вообще)?

Все еще IO монада чувствует себя даже если не волшебство, но особенное.

  • вы не можете избежать IO монады, как вы можете с другими монадами
  • действия IO может выполняться только с помощью функции main
  • IO всегда на дне монады трансформаторов цепи
  • реализация IO монада неясна, а в исходном коде показаны некоторые внутренние компоненты Haskell

Каковы причины для очков выше? Что делает IO таким особенным?

Обновление: в чистом коде оценки не имеет значения. Но это имеет значение при выполнении ввода-вывода (мы хотим сохранить клиента, прежде чем читать его). Из того, что я понимаю, монада Мороза дает нам такие заказывающие гарантии. Является ли это собственностью монады вообще или что-то особенное для монады IO?

ответ

2

Аналогичные утверждения могут быть сделаны в отношении монады ST или, возможно, монады STM (хотя вы можете фактически реализовать ее поверх IO).

В основном такие вещи, как монада-читатель, монада-ошибка, монада-писатель и т. Д., - это всего лишь чистый код. Монады ST и IO являются единственными, которые действительно нечистые вещи (мутация состояния и т. Д.), Поэтому они не могут быть определены в чистом Haskell. Они должны быть «жестко связаны» в компиляторе где-то.

7

вы не можете избежать IO монады, как вы можете с другими монадами

Я не уверен, что вы подразумеваете под “ ” побега. Если вы имеете в виду, как-то разворачиваете внутреннее представление монадических значений (например, список -> последовательность cons-cells) –, что является детальностью реализации. Фактически, вы можете определить an IOemulation 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 является одним из самых серьезных нарушителей спокойствия (и лучше всего избегать, во все времена).

+0

Когда я говорю «бегство» или «бег», я имею в виду функции запуска *, которые позволяют нам выполнять действия штата или читателя. Я думаю, что нет безопасной функции ввода-вывода. Было бы неплохо понять, почему – damluar

+0

Не могли бы вы прояснить ** обновление **? – damluar

+0

Эти 'run *' функции do _not_ "выполняют" что угодно. Они действительно просто раскрывают внутреннее представление. В случае с «IO» это не экспортируется официально (но, как я сказал дважды, существуют альтернативные реализации «IO», которые сводятся к простой государственной монаде). – leftaroundabout

Смежные вопросы