Тот факт, что функциональный язык является функциональным (может быть, даже полностью чистым, как Haskell!), не означает, что программы, написанные на этом языке, должны быть чистыми при запуске.
Подход Haskell, например, при работе с побочными эффектами можно объяснить довольно просто: пусть вся программа сама по себе будет чистой (это означает, что функции всегда возвращают одни и те же значения для одних и тех же аргументов и не имеют никаких побочных эффектов), но пусть возвращаемое значение функции main
будет действием, которое можно запустить.
Пытаясь объяснить это с помощью псевдокода, вот некоторая программа на императивном, нефункциональном языке:
main:
read contents of abc.txt into mystring
write contents of mystring to def.txt
Приведенная выше процедура main
представляет собой ряд шагов, описывающих выполнение ряда действий.
Сравните это с чисто функциональным языком, таким как Haskell. В функциональных языках все является выражением, включая основную функцию. Таким образом, можно прочитать эквивалент вышеприведенной программы следующим образом:
main = the reading of abc.txt into mystring followed by
the writing of mystring to def.txt
Итак, main
— это выражение, которое при вычислении возвращает действие, описывающее, что нужно сделать, чтобы выполнить программу. Фактическое выполнение этого действия происходит за пределами мира программистов. И это действительно так; ниже приведена реальная программа на Haskell, которую можно скомпилировать и запустить:
main = readFile "abc.txt" >>= \ mystring ->
writeFile "def.txt" mystring
Можно сказать, что a >>= b
означает «действие a
, за которым следует результат a
, переданный действию b
» в этой ситуации, а результатом оператора являются объединенные действия a и b. Вышеприведенная программа, конечно, не идиоматична на языке Haskell; можно переписать его следующим образом (удалив лишнюю переменную):
main = readFile "abc.txt" >>=
writeFile "def.txt"
... или, используя синтаксический сахар и do-нотацию:
main = do
mystring <- readFile "abc.txt"
writeFile "def.txt" mystring
Все вышеперечисленные программы не только эквивалентны, но и идентичны с точки зрения компилятора.
Вот как файлы, системы баз данных и веб-серверы могут быть написаны как чисто функциональные программы: путем потоковой передачи значений действий через программу, чтобы они объединялись и, наконец, оказывались в функции main
. Это дает программисту огромный контроль над программой, и именно поэтому чисто функциональные языки программирования так привлекательны в некоторых ситуациях.
person
dflemstr
schedule
06.12.2011