-- лямбда исчисления Чёрч
-- машина М0, хотим добавить к ней переменные и функции
-- форма\ьно опреде\иммашину М1, которая умеет исчислять:
-- (x+y-1)*2
-- если Е выражение а х переменная, то \x.E выражение, где \ - лямбда
-- если Е1 и Е2 выражение, то (E1)Е2 выражение
-- \x.(x+y-1)*2 по значению x возвращает функцию, зависящаю от x
-- (\x.(x+y-1)*2)3 при x = 3 -> (3+y-1)*2 -> (2+y)*2
-- М1 упрощает такие штуки, пока есть что упрощатьави
-- альфа преобразование - замена машиной значения под \
-- бета преобразование - подставление аргумента вместо переменной(редукция)
-- дельта преобразование - применение машины М0, т.е. упрощение выражения
-- Теорема Чёрча
-- о том, что результаты однозначны с точностью до альфа-преобразования(имен переменных) вне зависимости от порядка преобразований (если нас не зациклит)
-- inc x = x+1 => inc = \x -> x+1
-- add x y = x+y => add = \xy -> x+y, \x -> (\y->x+y)
-- x:xs - голова:хвост
len::[a]->Int
-- len [] = 0;
-- len (x:xs) = 1 + len xs
len xs = len' xs 0 where
len' [] n = n;
len' (x:xs) n = len' xs (n+1)
main = print $ show $ len [1,2,3,4,5,6,7,8,9,10] --[1..10], [1,3..10] = [1,3,5,7,9,] [1..] = бесконечный список с 1
-- генераторы списков
f xs = [2*x|x <- xs, x>0]
[(x,y,z)|x<-[0,1], y<-[0,1], z<-[0,1]] -- самый правый меняется быстрее
-- 000 001 010 011 100 101 110 111
tirplex::Int->[(Int, Int, Int)]
triplex n = [(a, b, c)| a<-[1..n], b<-[1..a], c<-[a..n], a*a + b*b == c*c]
-- ######################################################################################################### --
String = [Char]
"abc" = ['a', 'b', 'c']
filter(\x->x>0) [-5, 5]
filter(>0) [-5, 5]
map (+1) [1..10]
map (/2) [1..10]
map (2/) [1..10]
map inc [1..10]
-- ######################################################################################################### --
-- как определить свою операцию
(*^*+*^*):: Int->Int->Int
(*^*+*^*)x y = x + y - 2
-- ######################################################################################################### --
-- map - функция высшего порядка, ибо ей на вход передается другая функция
-- zipWith (binFun, xs, ys)
zipWith (+) [1..3][4..6] -- => [1+4, 2+5, 3+6] => [5,7,9]
zip xs ys
zip [1..3] [4..6] --=>[(1,4), (2,5), (3,6)]
-- могут работать со списками разной длины, но результат будет равен по длине меньшему
unzip [(1,4), (2,5), (3,6)] --=> ([1..3], [4..6])
dot xs ys = sum $ zipWith (*) xs ys --скалярное произведение
-- ######################################################################################################### --
-- 1 1 2
-- \ /
-- 1 1 2
fibb = 1:1:(zipWith(+) fibb (tail fibb))
f n = fibb !! n --n-элемент списка fibb