Поскольку побочные эффекты нарушают ссылочную прозрачность, не противоречат ли они функциональным языкам?Как функциональные языки моделируют побочные эффекты?
ответ
Есть два метода, которые используются чисто функциональными языками программирования для моделирования побочных эффектов:
1) Тип мира, который представляет собой внешнее состояние, в котором каждое значение этого типа гарантируется системой типа, которые будет использоваться только один раз.
На языке, использующем этот подход, функции print
и read
могут иметь типы (string, world) -> world
и world -> (string, world)
соответственно.
Они могут быть использованы как это:
let main w =
let w1 = print ("What's your name?", w) in
let (str, w2) = read w1 in
let w3 = print ("Your name is "^name, w2) in
w3
Но не так, как это:
let main w =
let w1 = print ("What's your name?", w) in
let (str, w2) = read w in
let w3 = print ("Your name is "^name, w2) in
w3
(потому что вес используется дважды)
Все встроенные функции с побочными эффектами будет принимать и возвращать мировое значение. Поскольку все функции с побочными эффектами являются либо встроенными, либо вызывают другие функции с побочными эффектами, это означает, что все функции с побочными эффектами должны принимать и возвращать мир.
Таким образом, невозможно вызвать функцию с побочными эффектами дважды с теми же аргументами, и ссылочная прозрачность не нарушена.
2) Монада IO, где все операции с побочными эффектами должны выполняться внутри этой монады.
При таком подходе все операции с побочными эффектами будут иметь тип io something
. Например, print
будет функцией с типом string -> io unit
и read
будет иметь тип io string
.
Единственный способ получить доступ к значению выполняемой операции будет заключаться в использовании операции «monadic bind» (например, >> = в haskell) с операцией ввода-вывода в качестве одного аргумента и функцией, описывающей, что делать с результат как другой операнд.
Пример из выше будет выглядеть следующим образом с монадической IO:
let main =
(print "What's your name?") >>=
(lambda() -> read >>=
(lambda name -> print ("Your name is "^name)))
Ваш №2 является деталь реализации для вашего # 1. Мода IO просто автоматически переносит это мировое состояние для вас, упаковывая и распаковывая его по мере необходимости за любым синтаксисом, который использует ваша монада. –
@JUST: Вы имеете в виду # 1 - деталь реализации №2, нет? Но тогда это не деталь реализации, если это интерфейс, который подвергается программисту. – sepp2k
Да, правильно. Сожалею. # 1 - деталь реализации №2. –
Насколько я понимаю, если вы хотите иметь побочные эффекты на функциональном языке, вы должны их явно закодировать.
Есть несколько вариантов, доступных для выполнения операций ввода/вывода в функциональном языке.
- Не будьте чисты. Многие функциональные языки не являются чисто функциональными. Более того, они поддерживают функциональное программирование, а не принуждают его выполнять. Это, безусловно, наиболее распространенное решение проблемы ввода-вывода в функциональном программировании. (Примеры: Lisp, Scheme, Standard ML, Erlang и т. Д.)
- Преобразование потока. Ранний ввод-вывод Haskell был выполнен таким образом. Если у вас есть , уточните мою ссылку ниже. (Подсказка: вы, вероятно, этого не делаете.)
- Продолжающий проход I/O («переходящий мир», упомянутый в других ответах). В этом случае вы передаете токен данных со своим вводом-выводом, который действует как необходимое «другое значение», чтобы сохранить ссылочную целостность живым. Это используется несколькими диалектами ML, если память служит.
- «Продолжение» или «мировая» вещь выше может быть обернута в различные типы данных, большинство (в) известных - использование монадов в этой роли в Haskell. Обратите внимание, что это, как ни странно, то же самое при обложках, но утомление отслеживания переменных состояния «мир»/«продолжение» удаляется.
a research dissertation, который исчерпывающе анализирует их.
Функциональный ввод-вывод - это постоянная область исследований, и есть другие языки, которые затрагивают эту проблему интересными и умиротворяющими способами. Hoare logic предлагается использовать на некоторых языках исследований. Другие (например Mercury) использовать uniqueness typing. Третьи (например, Clean) используют effect systems. Из них у меня очень ограниченное воздействие только на Меркурий, поэтому я не могу комментировать подробности. Есть paper, который подробно изучает систему ввода-вывода Clean, однако, если вас интересует это направление.
- 1. Побочные эффекты от молнии?
- 2. Пользовательские побочные эффекты геттера
- 3. Побочные эффекты в Fluxible?
- 4. LD_LIBRARY_PATH побочные эффекты
- 5. Когда возникают побочные эффекты?
- 6. Javassist: Побочные эффекты ClassPool.makeClass()?
- 7. внутренние побочные эффекты HTML?
- 8. Устранить побочные эффекты Bacon.js
- 9. reloadRowsAtIndexPaths побочные эффекты?
- 10. Linq Любой() побочные эффекты
- 11. Как обрабатывать побочные эффекты Java
- 12. Apppool recycle побочные эффекты
- 13. Корневые побочные эффекты доступа
- 14. Побочные эффекты в C
- 15. побочные эффекты сбора мусора?
- 16. Побочные эффекты памяти setvbuf
- 17. Mocking побочные эффекты
- 18. BX побочные эффекты?
- 19. Побочные эффекты с Mocha
- 20. Confused about функциональные языки
- 21. Набираются функциональные языки быстрее?
- 22. Функциональные языки: реальные примеры
- 23. , имитирующие побочные эффекты с нитями
- 24. JSONP, есть ли побочные эффекты?
- 25. Scala recursion no побочные эффекты
- 26. Переименовать() внутренние побочные эффекты функции?
- 27. Побочные эффекты в языке Go
- 28. Принудительные побочные эффекты в python
- 29. Предотвратить побочные эффекты в Рубине
- 30. Каковы побочные эффекты использования EmptyWorkingSet?
http://stackoverflow.com/questions/2158050/what-are-the-alternative-of-monads-to-use-io-in-pure-functional-programming/2158637#2158637 –