I/O в Haskell является функциональным?

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

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

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

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

Ответы

Ответ 1

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

   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))

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

Лучшее введение в семантические решения, лежащие в основе этого проекта, "The Awkward Squad" ,

enter image description here

Ответ 2

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

Ответ 3

Подумайте об этом так. Он фактически не выполняет команды ввода-вывода. Мода IO - это чистое значение, которое инкапсулирует "обязательное вычисление", которое нужно выполнить (но на самом деле оно не выполняется). Вы можете поместить монады (вычисления) вместе в более крупное "вычисление" чистым способом, используя операторы монады и конструкции, подобные "делать". Тем не менее, ничто не "казнено" как таковое. Фактически, в какой-то мере вся цель программы Haskell состоит в том, чтобы собрать большое "вычисление" , которое является его значением main (которое имеет тип IO a). И когда вы запускаете программу, выполняется это "вычисление" .

Ответ 4

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

Ответ 5

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