-
-
-
-Функциональное программирование
-
-
-
-
-Функциональное программирование:
-
-функции – это тоже данные.
-
-Int -> Bool
(функция) – ровно такие же данные как и Int
. Их также можно складывать в структуры, передавать как аргументы и т. п.
-
-
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
-
- |
-
-
-
-
-
-
-
-
-
-
- static <T> T f(T x)
- static <T> T g(T x)
- |
-
- f :: a -> a
- g :: a -> a
- |
-
-
-
-
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-h = f . g
-h x == f (g x)
-
-
-
-
-
-моноид
-
-
-
-
-Моноид
-Бинарная асоциативная операция
-(.) :: (a -> a) -> (a -> a) -> (a -> a)
-Нейтральный элемент
-
-
-
-
-
-Чисто функционаьлный
-Все что функция может сделать – посмотреть на свои аргументы это вернуть значение.
-
-
-
-
-Referential transparency
-(Любую константу можно заменить на само значение)
-int x = 8;
-int y = x++;
-System.out.println(y + " might be the same as " + y);
-int x = 8;
-System.out.println(x++ + " might be the same as " + x++);
-
-
-
-
-Нет переменных, циклов и условных переходов
-Зато есть константы и нормальная рекурсия (А переходов вообще нет)
-
-
-
-Очень ленивый
-xs = [4, 1, 3, 2]
-xs' = sort xs
-print xs
-
-
xs'
не нужен чтобы распечатать xs
, поэтому сортироваться ничто не будет. (Зачем делать то, что можно не делать)
-
-
-
-
-Если хотите быстро и просто потыкаться, тут есть интерктивная штука:
-haskell.org
-
-
-
-
-
-add2 :: Int -> Int
-add2 x = x + 2
-Все функции и константы всегда обозначаются словами с маленькой буквы без пробелов.
-(Константы это просто функции с нулем аргументов.)
-
-
-
-Pattern mathcing
-fixBuz :: Int -> String
-divide8 3 = "Fiz"
-divide8 5 = "Buz"
-divide8 15 = "FizBuz"
-divide8 _ = "Some other number"
-Так матчить можно произвольные структуры произвольного уровня вложенности.
-_
– специальное название константы, которое говорит что вам все равно что в ней лежит.
-
-
-
-
-
-data Foo = Bar
-foo :: Bar
-foo = Bar
-Foo
– тип структуры. Bar
– конструктор структуры.
-Тут у Foo
всего одно значение Bar
.
-
-
-
-Произведение типов
-(обычные поля структур)
-
-data PersonType = Person String Int
-vasya :: PersonType
-vasya = Person "Vasya" 8
--- тип можно не укзывать
-petya = Person "Petya" 5
-getName :: PersonType -> String
-getName (Person name _) = name
-greetPerson :: PersonType -> String
-greetPerson p = "Hello, " ++ getName p
-greetPerson petya
--- "Hello, Petya"
-
-
-
-Еще немного функций
-greetPerson :: PersonType -> String
-greetPerson p = "Hello, " ++ getName p
-greetPerson :: PersonType -> String
-greetPerson p = "Hello, " ++ name
- where
- name = getName p
-greetPerson :: PersonType -> String
-greetPerson p = "Hello, " ++ name
- where
- getName' (Person name _) = name
- name = getName' p
-
-
-
-data PersonType = Person String Int
-
-getName :: PersonType -> String
-getName (Person name _) = name
-greetName :: String -> String
-greetName name = "Hello, " ++ name
-greetPerson :: PersonType -> String
-greetPerson p = greetName (getName p)
-greetPerson :: PersonType -> String
-greetPerson = greetName . getName
-greetPerson petya
--- "Hello, Petya"
-(greetName . getName) petya
--- "Hello, Petya"
-
-
-
-Суммы типов
-
-
-x :: Bool
-x = True
-y = False
-ifThenElse :: (Bool, a, a) -> a
-ifThenElse (True, a, _) = a
-ifThenElse (False, _, b) = b
-ifThenElse (True, "Hello", "World")
--- "Hello"
-ifThenElse (False, "Hello", "World")
--- "World"
-
-
-
-data CircleType = Circle Double Double Double
-data RectangleType = Rectangle Double Double Double Double
-data Shape =
- CircleShape CircleType | RectangleShape RectangleType
-surface :: Shape -> Double
-surface (CircleShape (Circle _ _ r)) =
- pi * r ^ 2
-surface (RectangleShape (Rectangle x1 y1 x2 y2)) =
- (abs (x2 - x1)) * (abs (y2 - y1))
-shape = CircleShape (Circle 0 0 2)
-surface shape
--- 12.566370614359172
-otherShape = RectangleShape (Rectangle 1 2 3 4)
-surface otherShape
--- 4.0
-
-
-
-
-Лямбда-выражения
-
-
-
-λ – \
(λ печатать тяжело)
-foo :: (Int -> Int) -> Int
-
-
-
-
-
-Давайте придумаем синтаксис для функции нескольких аргументов!
-
-
-
-x, y :: Int
-x = 42
-y = 69
-xPlusY :: Int
-xPlusY = add x y
-Применение функции – лево-ассоциативно
-
-
-
-add :: Int -> (Int -> Int)
-
-
-
-add :: Int -> (Int -> Int)
-Тип ->
– право-ассоциативный
-
-
-
-
-
-
-Любая функция берет строго один аргумент.
-Функция нескольких аргументов все равно берет строго одтн аргумент и возвращает функцию, которая берет следйющий.
-(И из-за того, что применение функции лево-ассоциативно, вызов таких не трубует особого синтаксиса.)
-
-
-
-Currying
-add :: Int -> Int -> Int
-add a b = a + b
-
-add :: Int -> (Int -> Int)
-
-
-
-
-
-Funny fact
-Оператор (например +
) – функция, название которой не содержит буквы и цифры.
-
-
-
-
-
-Funny fact 2
-Оператор можно превратить в функцию, окружив его скобками.
-add :: Int -> Int -> Int
-add x y = x + y
-
-
-
-
-
-Funny fact 3
-Функцию можно превратить в оператор, окружив ее обратными кавычками.
-add :: Int -> Int -> Int
-add x y = x + y
-
-
-
-
-
-
-Односвязный список
-data IntList = Cons Int IntList | Nil
-Cons :: Int -> IntList -> IntList
-Nil :: IntList
-nums :: IntList
-nums = 1 `Cons` (2 `Cons` (3 `Cons` Nil))
-
-sum (Cons x xs) = x + sum xs
-sum Nil = 0
-sum (Cons x xs) = x + sum xs
-
-
-
-
-take :: Int -> IntList -> IntList
-take _ Nil = Nil
-take 0 _ = Nil
-take n (Cons x xs) = Cons x (take (n - 1) xs)
-nums :: IntList
-nums = 1 `Cons` (2 `Cons` (3 `Cons` Nil))
-take 2 nums
--- Cons 1 (Cons 2 Nil)
-take 1029 nums
--- Cons 1 (Cons 2 (Cons 3 Nil))
-take 0 nums
--- Nil
-
-
-
-
-repeat n = Cons n (repeat n)
-repeat 8
--- Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (Cons 8 (...
-(take 3 . repeat) 8
--- Cons 8 (Cons 8 (Cons 8 Nil))
-(sum . take 3 . repeat) 8
--- 24
-
-
-
-
-
-
-Наша самодеятельность
- |
-
-В стандартной библиотеке
- |
-
-
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
-
- |
-
-
-
-
-
-repeat
, sum
и take
тоже есть в стандартной библиотеке.
-
-
-
-
-quicksort :: [Int] -> [Int]
-quicksort (x:xs) =
- quicksort smaller ++ [x] ++ quicksort larger
- where
- smaller = filter (< x) xs
- larger = filter (>= x) xs
-
-
-
-filter :: (Bool -> Int) -> [Int] -> [Int]
-filter f (x:xs) =
- if f x
- then filter f xs
- else x:(filter f xs)
-filter _ [] = []
-filter f (x:xs) =
- if f x
- then filter f xs
- else x:(filter f xs)
-
-
-
-quicksort :: [Int] -> [Int]
-quicksort (x:xs) =
- quicksort smaller ++ [x] ++ quicksort larger
- where
- smaller = filter (< x) xs
- larger = filter (>= x) xs
- filter _ [] = []
- filter f (x:xs) =
- if f x
- then filter f xs
- else x:(filter f xs)
-
-
-
-quicksort :: [Int] -> [Int]
-quicksort [] = []
-quicksort (x:xs) =
- quicksort smaller ++ [x] ++ quicksort larger
- where
- smaller = filter (< x) xs
- larger = filter (>= x) xs
- filter _ [] = []
- filter f (x:xs) =
- if f x
- then filter f xs
- else x:(filter f xs)
-quicksort [2, 1, 3, 4]
--- [1, 2, 3, 4]
-
-
-
-filter
тоже есть в стандартной библиотеке.
-
-
-Где и как смотреть “стандартную библиотеку”
-
-
-
-
-Hackage
-(Там вам нужен только пакет base
. Ссылка ведет прямо на него.) Еще если там нажать s
, то будет поиск.
-Hoogle
-Это поиск по типам. Например: Int -> [Int] -> [Int]
(Тут вам опять же нужен только пакет base
. Нужно чтобы справа было "package:base".) –>
-
-
-