diff --git a/1.html b/1.html index e69de29..f5f79b0 100644 --- a/1.html +++ b/1.html @@ -0,0 +1,703 @@ + + + + + + + 1 + + + + + + + + + + + + + +
+
+ + +
+

Функциональное программирование

+ +
+
+ +

Функциональное программирование:

+
+

функции – это тоже данные.

+
+

Int -> Bool (функция) – ровно такие же данные как и Int. Их также можно складывать в структуры, передавать как аргументы и т. п.

+
+
+

нотация

+
+
+ + + + + + + + + + + + + + +
+
  int x;
+
+
  x :: Int
+
+
  int f(int x)
+
+
  f :: Int -> Int
+
+
  static <T> T f(T x)
+
+
  f :: a -> a
+
+
+
+ + + + + + + + + + + + + + + +
+
  static <T> T f(T x)
+
+
  f :: a -> a
+
+
  f(x);
+
+
  f x
+
+
  f(x, y);
+
+
  f x y
+
  f x y = (f x) y
+
+ +
+
+ + + + + + + + + + +
+
  static <T> T f(T x)
+  static <T> T g(T x)
+
+
  f :: a -> a
+  g :: a -> a
+
+
  f(g(x));
+  g(f(x));
+
+
  f (g x)
+  g (f x)
+
+
+
+

Композиция

+
+
+ +
f :: a -> a
+g :: a -> a
+
f (g x)
+
(f . g) x == f (g x)
+
h = f . g
+h x == f (g x)
+
+
+ +
f :: a -> a
+g :: a -> a
+
h :: a -> a
+h = f . g
+

моноид

+ +
+
+ +

Моноид

+

Бинарная асоциативная операция

+
(.) :: (a -> a) -> (a -> a) -> (a -> a)
+

Нейтральный элемент

+
id :: a -> a
+id x = x
+
+
+

Haskell

+
+
+ +

Чисто функционаьлный

+

Все что функция может сделать – посмотреть на свои аргументы это вернуть значение.

+ +
+
+ +

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"
+
+
+ +

Суммы типов

+ +
data Bool = False | True
+
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
+
+
+

И еще немного функций

+
+
+ +

Лямбда-выражения

+
add8 :: Int -> Int
+
add8 x = x + 8
+
add8 = \x -> x + 8
+

λ – \ (λ печатать тяжело)

+
foo :: (Int -> Int) -> Int
+
foo add8
+
foo (\x -> x + 8)
+
+
+ +

Давайте придумаем синтаксис для функции нескольких аргументов!

+
+
+ +
x, y :: Int
+x = 42
+y = 69
+
xPlusY :: Int
+xPlusY = add x y
+

Применение функции – лево-ассоциативно

+
xPlusY = (add x) y
+
xPlusY = f y
+f = add x
+
f :: Int -> Int
+
add :: Int -> (Int -> Int)
+
+
+ +
add :: Int -> (Int -> Int)
+

Тип -> – право-ассоциативный

+
add :: Int -> Int -> Int
+
add a b = a + b
+
add = \a b -> a + b
+
+
+ +

Любая функция берет строго один аргумент.

+

Функция нескольких аргументов все равно берет строго одтн аргумент и возвращает функцию, которая берет следйющий.

+

(И из-за того, что применение функции лево-ассоциативно, вызов таких не трубует особого синтаксиса.)

+
+
+ +

Currying

+
add :: Int -> Int -> Int
+add a b = a + b
+
add8 :: Int -> Int
+
add :: Int -> (Int -> Int)
+
add8 = add 8
+
add8 3
+-- 11
+
+
+ +

Funny fact

+

Оператор (например +) – функция, название которой не содержит буквы и цифры.

+
x +&+ y = x + y
+
8 +&+ 9
+-- 17
+
+
+ +

Funny fact 2

+

Оператор можно превратить в функцию, окружив его скобками.

+
add :: Int -> Int -> Int
+add x y = x + y
+
add = (+&+)
+
add = (+)
+
+
+ +

Funny fact 3

+

Функцию можно превратить в оператор, окружив ее обратными кавычками.

+
add :: Int -> Int -> Int
+add x y = x + y
+
add 8 9
+-- 17
+
8 `add` 9
+-- 17
+
+
+

Список

+
+
+ +

Односвязный список

+
data IntList = Cons Int IntList | Nil
+
Cons :: Int -> IntList -> IntList
+Nil :: IntList
+
nums :: IntList
+nums = 1 `Cons` (2 `Cons` (3 `Cons` Nil))
+
sum :: IntList -> Int
+
sum (Cons x xs) = x + sum xs
+
sum Nil = 0
+sum (Cons x xs) = x + sum xs
+
sum nums
+-- 6
+
+
+ +
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 :: Int -> IntList
+
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
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+Наша самодеятельность + +В стандартной библиотеке +
+
  IntList
+
+
  [Int]
+
+
  IntList
+
+
  [Int]
+
+
  Nil
+
+
  []
+
+
  Cons
+
+
  :
+
+
  Cons 3 (Cons 4 Nil)
+
+
  3 : 4 : []
+
  [3, 4]
+
+
+
+ +

repeat, sum и take тоже есть в стандартной библиотеке.

+
+
+

QuickSort

+
+
+ +
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 тоже есть в стандартной библиотеке.

+
+
+

Где и как смотреть “стандартную библиотеку”

+
+
+ +
    +
  1. Hackage

    +

    (Там вам нужен только пакет base. Ссылка ведет прямо на него.) Еще если там нажать s, то будет поиск.

  2. +
  3. Hoogle

    +

    Это поиск по типам. Например: Int -> [Int] -> [Int] (Тут вам опять же нужен только пакет base. Нужно чтобы справа было "package:base".)

  4. +
+
+
+
+ + + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..f4de483 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +## Lecures + +1. Lecture 1 [md](https://github.com/ikoHSE/sc-lectures/blob/master/1.md) [web](https://ikohse.github.io/sc-lectures/1.html) + 1. Functions as a monoid + 2. Functions + 3. Pattern matching + 5. Product types + 6. Sum types + 7. Lambdas + 4. Functions of multiple arguments + 5. Currying + 7. Lists + 9. Quicksort diff --git a/build.sh b/build.sh index 400d3fa..6f18ec8 100755 --- a/build.sh +++ b/build.sh @@ -3,5 +3,8 @@ for file in *.md do base=$(basename $file .md) - pandoc -i $file -t revealjs -s --highlight-style=breezeDark --include-in-header=style.html >"$base.html" + if [base != "README"] + then + pandoc -i $file -t revealjs -s --highlight-style=breezeDark --include-in-header=style.html >"$base.html" + fi done