Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
var NatToChurch = function (n) {
return n == 0 ? Zero : function (f) {
return function (x) {
return f(NatToChurch(n - ChurchToNat(Succ(Zero)))(f)(x));
};
};
};
var ChurchToNat = function (n) {
return n(function (x) {
return x + 1;
})(0);
};
natToChurch 0 = \f -> id
natToChurch n = \f -> f . (natToChurch (n - 1))
churchToNat f = f (+1) 0
fact n = product [1..n]
fact 0 = 1
fact n = n * fact (n - 1)
Правда, я ни разу пока не встречал задачи, которую было бы сильно сложнее написать императивным/объектным стилем.
qsort [] = []
qsort (x:xs) = qsort [a | a <- xs, a <= x] ++ [x] ++ qsort [a | a <- xs, a > x]
solve x = go where go = fmap ($ go) x
main = print $ solve [const 42 -- константа 42
, succ . (!! 0) -- нулевая ячейча + 1
, sum . take 2] -- сумма первых двух ячеек
А на том же C++ можно по всякому — и так, и эдак, и с подвывертом.
Быстрая сортировка ведь есть в стандартной библиотеке C++?
Что касается программы с ячейками — во-первых, я не очень понял задачу.
Но ни разу почему-то не пришлось решать задачи, которые я посчитал бы удобным решать на чисто функциональных языках
Еще мне нравится такой пример, вполне себе практический, представим себе электронную таблице типа экселевской, пусть это будет список с ячейками в которых лежат значения и функции зависящие от этих значений, попробуем написать код вычисляющий значения для всех ячеек:
$ cat q.hs
solve x = go where go = fmap ($ go) x
main = print $ solve [const 42 -- константа 42
, succ . (!! 0) -- нулевая ячейча + 1
, sum . take 2] -- сумма первых двух ячеек
$ runhaskell q.hs
[42,43,85]
Я же вижу, что не всё в этом мире функция.
Бывают же константы, бывают процедуры, бывают контейнеры (объекты, структуры и т.п.)
зачем нужен подход «всё — функция»
function NatToChurch (n) {
return n == 0 ? Zero : Succ(NatToChurch(n-1));
}
var True = function (x) {
return function (y) {
return x;
};
};
var False = function (x) {
return function (y) {
return y;
};
};
var If = function (p) {
return function (t) {
return function (e) {
return p(t)(e);
}
};
};
true = \x -> \y -> x
false = \x -> y -> y
if = \cond -> \yes -> \no -> cond yes no
var If = function (p) { return p; }
if = \cond -> cond
if = \cond -> cond
if = id
if' = id
fact n = isZero (n) (id) (n . (fact $ dec $ n))
Вычисление факториала на числах Чёрча