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
Это не функциональный код. Почему это должно быть?