Ввод / вывод в Haskell является функциональным? - PullRequest
15 голосов
/ 19 июня 2011

Я только начинаю , чтобы взглянуть на Haskell (мой предыдущий опыт FP в Схеме), и я наткнулся на этот код :

do { putStrLn "ABCDE" ; putStrLn "12345" }

Для меня это процедурное программирование, во всяком случае - особенно из-за последовательной природы побочных эффектов.

Кто-нибудь, пожалуйста, объясните, как этот код "функционален" в любом отношении?

Ответы [ 5 ]

20 голосов
/ 19 июня 2011

Хотя это и выглядит как процедурная программа, приведенный выше синтаксис преобразуется в функциональную программу, например, так:

   do { putStrLn "ABCDE" ; putStrLn "12345" }
=>
   IO (\ s -> case (putStrLn "ABCDE" s) of
                  ( new_s, _ ) -> case (putStrLn "12345" new_s) of
                                      ( new_new_s, _) -> ((), new_new_s))

То есть ряд вложенных функций, которые имеют уникальный параметр world, пронизываемый черезих, последовательность вызовов примитивных функций "процедурно".Этот дизайн поддерживает кодирование императивного программирования на функциональный язык.

Лучшим введением в семантические решения, лежащие в основе этого дизайна, является "Неуклюжий отряд" paper,

enter image description here

13 голосов
/ 20 июня 2011

Я не думаю, что мы можем дать четкий ответ на этот вопрос, потому что «функционал» - это нечеткое понятие, и существуют противоречивые представления о том, что он означает. Поэтому я предпочитаю предложенный Питером Лэнденом термин замены «денотативный», который является точным и содержательным и, для меня, сердцем и душой функционального программирования и того, что делает его подходящим для рациональных рассуждений. См. эти комментарии , где приведены некоторые указания на определение Лэндена. IO означает , а не обозначает.

5 голосов
/ 19 июня 2011

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

3 голосов
/ 19 июня 2011

Это монада . Прочитайте о do-notation для объяснения того, что происходит за обложками.

0 голосов
/ 20 июня 2011

Это не функциональный код. С чего бы это?

...