Алгебраические типы данных
DESCRIPTION
Введение в типы данных используемые в языках Haskell, ML, SML, Ocaml, F#. Какие типы используются, как они создаются и зачем нужны. Не требуется никакого знания ни одного из перечисленных языков.TRANSCRIPT
Алгебраические типы данных
Алгебраические типы данных
- типы получаемые из других типов с помощью алгебраических операций
Простые типы
● Int
● Double
● Bool
● Char
● String
Функции с 1 аргументом
incr x = x + 1
Функции с 1 аргументом
incr x = x + 1
fact 0 = 1
fact n = fact (n-1) * n
Функции с 2 аргументами
add (x, y) = x + y
Функции с 2 аргументами
add (x, y) = x + y
mul (0, _) = 0
mul (1, x) = x
mul (n, x) = mul (n-1, x) + x
Типы функций
incr :: Int -> Int
fact :: Int -> Int
add :: (Int, Int) -> Int
mul :: (Int, Int) -> Int
Горькая правда о парах
mul :: (Int, Int) -> Int
mul (n, x) = n * x
mul pair = (fst pair) * (snd pair)
Что такое пара?
● Просто два значения собранные вместе.
● Множество пар – декартово произведение множеств.
● Пара – составной тип.
Как же сделать функцию нескольких аргументов?
● Никак.
● Эмулировать с помощью пар.
● Эмулировать с помощью каррирования.
Лямбды
incr x = x + 1
incr = \x -> x + 1
Лямбды
incr x = x + 1
incr = \x -> x + 1
incr 10 -- 11
Лямбды и каррирование
add = (\x -> (\y -> x + y))
Лямбды и каррирование
add = (\x -> (\y -> x + y))
add x = (\y -> x + y)
Лямбды и каррирование
add = (\x -> (\y -> x + y))
add x = (\y -> x + y)
add x y = x + y
Каррирование
add x y = x + y
add 3 4 -- 7
Каррирование
add x y = x + y
add 3 4 -- 7
(add 3) 4 -- 7
Тип каррированной функции
add :: Int -> (Int -> Int)
Тип каррированной функции
add :: Int -> (Int -> Int)
add :: Int -> Int -> Int
Тип каррированной функции
add :: Int -> (Int -> Int)
add :: Int -> Int -> Int
-- не то же самое:
add :: (Int -> Int) -> Int
Частичное применение
add10 = add 10
add10 3 -- 13
Частичное применение
add10 = add 10
add10 3 -- 13
map (add 5) [1,2,3]
-- [6,7,8]
Алгебраические типы данных
● Типы произведения.
● Типы суммы.
Тип-произведение
– имеет по значению для каждого из своих компонентов
Тип-произведение
– декартово произведение своих составляющих
Тип-произведение
● Кортежи● Записи● struct в c● Объекты
Кортежи
(1, 2, 3) :: (Int, Int, Int)
('x', 'a') :: (Char, Char)
('x', 42) :: (Char, Int)
Кортежи
(incr, mul) :: (Int -> Int, (Int, Int) -> Int)
(1,(2,3)) :: (Int,(Int,Int))
Записи
data Point = Point Int Int
data Person
= Person {name :: String, age :: Int}
Записи
Point 10 20
Person {name = "Alice", age = 25}
Person {age = 25, name = "Alice"}
Person "Alice" 25
Конструкторы записей
Person :: String -> Int -> Person
(Person "Alice") :: Int -> Person
Конструкторы записей
Person :: String -> Int -> Person
(Person "Alice") :: Int -> Person
map (Person "Alice") [10, 20, 30]
Конструкторы записей
lame (Person n a) = n ++ " is "
++ (show a) ++ " years old"
lame p = (name p) ++ " is "
++ (show (age p)) ++ " years old"
Тип-сумма
– имеет значение одного из своих компонентов за раз
Тип-сумма
– объединение множеств своих составляющих
Тип-сумма
● union в c● variant● динамические типы
Объединения
data Value = Exact Double
| Range Double Double
data Gender = Male | Female
data Person = Person String Gender
Объединения
valueLen (Exact _) = 0
valueLen (Range x y) = y - x
Объединения
data NamedVal = NamedVal String Value
f (NamedValue s v) = ...
f (NamedValue s (Exact x)) = ...
f (NamedValue s (Range x y)) = ...
Полиморфизм функций
add :: (Int, Int) -> Int
add :: (Double, Double) -> Double
...
Полиморфизм функций
identity x = x
identity :: a -> a
Полиморфизм функций
identity x = x
identity :: a -> a
flip (x, y) = (y, x)
flip :: (a, b) -> (b, a)
Полиморфизм типов
data Maybe a = Nothing | Just a
data Either a b = Left a | Right b
Полиморфизм типов
justP (x, y) = (Just x, Just y)
Полиморфизм типов
justP (x, y) = (Just x, Just y)
justP :: (a, b) -> (Maybe a, Maybe b)
Полиморфные рекурсивные типы
data List a = Empty | Cons a (List a)
Empty
Cons 1 Empty
Cons 1 (Cons 2 Empty)
Полиморфные рекурсивные типы
data List a = Empty | Cons a (List a)
Cons "1" (Cons "2" Empty)
-- не сработает:
Cons "1" (Cons 2 Empty)
Полиморфные рекурсивные типы
len Empty = 0
len (Cons _ tail) = 1 + len tail
len :: List a -> Int
Настоящие списки
data [a] = [] | a : [a]
length [] = 0
length x:xs = 1 + length xs
Настоящие списки
data [a] = [] | a : [a]
type String = [Char]
Спасибо.