Haskell Type System
Ивашнёв Дмитрий
email: 0xff0x666@gmail.com
jabber: xffox@headcounter.org
25 апреля 2014 г.
Парадигма
• Функциональный язык (functional)
• Чисто функциональный язык (purely functional)
• Язык с ленивой моделью вычи...
Функциональный язык (functional)
fact(n) =
1 if n = 0
n × fact(n − 1) otherwise
Функциональный язык (functional)
module Fact
where
fact 0 = 1
fact n = n*fact (n -1)
Чисто функциональный язык (purely
functional)
Представьте что все const
Чисто функциональный язык (purely
functional)
f (x) = ax2
+ bx + c
Решить для x при f (x) = 0
∆ = b2
− 4ac
x1,2 =
−b ±
√
∆...
Чисто функциональный язык (purely
functional)
module Discriminant
where
solveQuadratic a b c =
let d = b*b - 4*a*c
in if d...
Чисто функциональный язык (purely
functional)
d = b * b - 4 * a * c
Списки (lists)
• [] - пустой список
• [1, 2, 42] - список с тремя элементами
• [[], [1], [1, 2], [1, 2, 42]] - список спис...
Списки (lists)
• [1, 2 .. 5] = [1, 2, 3, 4, 5]
• [1, 2 .. ]
• [1 .. ]
Списки (lists)
Добавление в список
42:[]
[42]
8:[42]
[8 ,42]
Списки (lists)
Сложность операций
length - O(n)
Проверка на пустой список: null
Не используйте length ls == 0
Привет C++ и...
Функции первого порядка
Функции могут передаваться в качестве параметров функций
odd 1
True
filter odd [1, 2, 3]
[1, 3]
Язык с ленивой моделью вычислений
(lazy)
filter odd [1, 2, 3, 4, 5]
filter odd [1, 2 .. 5]
[1, 3, 5]
Язык с ленивой моделью вычислений
(lazy)
filter odd [1 ..]
take 3 (filter odd [1 ..])
[1, 3, 5]
Язык со статической типизацией (static
typing)
Проверка типов на этапе компиляции
Язык со строгой типизацией (strong
typing)
Явные приведения между всеми типами
Int, Float, ...
С чего начать
http://www.haskell.org/
Компилятор
http://www.haskell.org/ghc/
Математическая нотация
Множества A и B
Функция F
F : A → B
Нотация типов в Haskell
Переменные типов: a и b
В данном случае на типы не накладывается никаких
ограничений
Функция f
f :...
Примеры
Переменные типов: a, b и c
Функция f
f :: a -> b -> c
Списки
f :: a -> [a]
Функции первого порядка
filter :: (a -> Bool) -> [a] -> [a]
map :: (a -> b) -> [a] -> [b]
foldr :: (a -> b -> b) -> b -> [...
Логика типов
Определение тела функции по ее типу
f :: a -> a
Логика типов
Определение тела функции по ее типу
f :: a -> a
Возможное решение
f a = a
f = id
id 42
42
Логика типов
Какие возможны реализации?
f :: a -> [a]
Выведение типов
Для функции fact
module Fact
where
fact 0 = 1
fact n = n*fact (n -1)
получим тип
fact :: (Eq a, Num a) => ...
Выведение типов
Все типы функций могут быть выведены автоматически на
этапе компиляции
Явное указание типа может помочь в ...
Выведение типов
C++11 добавляет выведение типа переменных – auto
auto value = 42;
auto value = 1 + 2;
auto value = f(42);
...
Алгебраические типы данных (Algebraic
Data Types)
Наиболее общий составной тип, представляющий собой
тип-сумму из типов-пр...
Тип с одним параметром
Множество A
Переменная типа a
data Name a = Constructor a
Тип с несколькими параметрами
Множества T, A и B
Переменные типа a и b
data Name a b = Constructor a b
тип-произведение
T ...
Тип с несколькими конструкторами
Множества T и A
Переменная типа a
data Name a = ContructorF a | ContructorS a
тип-сумма
A...
Все вместе
Множества T, A, B
Переменные типа a и b
data Name a b = ContructorF a b | ContructorS a
сумма произведений
Af =...
Дизъюнктное объединение (Disjoint
union)
i∈I
{(x, i) : x ∈ Ai }
Зачем
• Формальное обощение: enum, struct, union
• Сопоставление параметров функций по шаблону
Параметры функций
data State a b = First a | Second b | Third a b
handle (First s) v = Second (f s)
handle (Second s) v = ...
enum
data Bool = True | False
data Color = Red | Green | Blue
enum Bool
{
TRUE ,
FALSE
};
struct
data State a b = St a b
struct State
{
int a;
int b;
};
union
data State a b = First a b | Second a
union State
{
struct
{
int a;
int b;
} first;
struct
{
int a;
} second;
};
Рекурсивные типы данных
Бинарное дерево
module Tree
where
data Tree a = Leaf | Node (Tree a) a (Tree a)
sumTree Leaf = 0
s...
Списки
List a = [] | (:) a (List a)
Полиморфизм
Позволяет строить суждения о типах зная только класс этих
типов
Класс описывает функции, реализуемые типом
Typeclasses
Моноид - множество с заданной на нем ассоциативной
бинарной операцией и нейтральным элементом.
(a · b) · c = a...
Typeclasses
module Monoid
where
class Monoid a where
binop :: a -> a -> a
identity :: a
twice :: Monoid a => a -> a
twice ...
Typeclasses
“In fact, trolls traditionally count like this: one, two, three . . .
many, and people assume this means they ...
Typeclasses
module TrollNum(TrollNum (..) , plus , binop , identity)
where
import Monoid
data TrollNum = Zero | One | Two ...
Typeclasses
import Monoid
import TrollNum
main = putStrLn $ show $ twice Two
Many
Операторы
Среднее арифметическое
module Ops
where
(-|-) a b = (a + b)/2
Pointfree style
Функции f (x), g(x) и z(x)
z(x) = f (g(x))
z = f . g
(.) :: (b -> c) -> (a -> b) -> a -> c
Pointfree style
Функция, прибавляющая 1 к переданному значению
addOne v = v + 1
addOne v = (+) v 1
addOne v = (+) 1 v
addO...
Pointfree style
Найти длину самого длинного слова в строке
module LongestWord
where
longestWord = (foldr max 0) . (map len...
Понятие
Это абстракция линейной цепочки связанных вычислений. Её
основное назначение - инкапсуляция функций с побочным
эфф...
Info
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> ...
Общий шаблон
• Тип с одним параметром m
• Получение значения (bind):
функция (»=) :: m a -> (a -> m b) -> m b
• Инъекция з...
Monad
IO
Как возможно IO в системе без побочных эффектов?
IO monad
Снова факториал
Хвостовая рекурсия
module XFact
where
xfact n = xfact ’ 1 n
where
xfact ’ v 0 = v
xfact ’ v n = xfact ’ (v...
Выведение типов
Модульная арифметика
module ModInt
where
newtype ModInt = ModInt {
fromModInt :: Int
}
deriving (Show)
ins...
DSL
import Fuzz
import DumbFuzzer
authRequest = "AUTH" ‘wait ‘ authResponses
getRequest = "GET" ‘wait ‘ getResponses
authR...
Fuzz I
module Fuzz(wait , report , (|->), (//) , other , fuzz , Fuzzer (..))
where
data Response r = Response (Msg , Reque...
Fuzz II
next f _ [Other request] = fuzz f request
next f resp (( Other request):rs) = next f resp (rs ++ [Other request ])...
Fuzzer
module DumbFuzzer
where
import Fuzz
data DumbFuzzer = DumbFuzzer
instance Fuzzer DumbFuzzer where
send _ m = do
put...
Литература
• Real World Haskell by Bryan O’Sullivan, John Goerzen, and
Don Stewart
• The Haskell Road to Logic, Math and P...
Haskell Type System with Dzmitry Ivashnev.
Upcoming SlideShare
Loading in …5
×

Haskell Type System with Dzmitry Ivashnev.

463 views

Published on

Slides from http://www.meetup.com/fsharpminsk/events/176930252/?comment_table_id=344084692&comment_table_name=event_comment

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
463
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
4
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Haskell Type System with Dzmitry Ivashnev.

  1. 1. Haskell Type System Ивашнёв Дмитрий email: 0xff0x666@gmail.com jabber: xffox@headcounter.org 25 апреля 2014 г.
  2. 2. Парадигма • Функциональный язык (functional) • Чисто функциональный язык (purely functional) • Язык с ленивой моделью вычислений (lazy) • Язык со статической типизацией (static typing) • Язык со строгой типизацией (strong typing)
  3. 3. Функциональный язык (functional) fact(n) = 1 if n = 0 n × fact(n − 1) otherwise
  4. 4. Функциональный язык (functional) module Fact where fact 0 = 1 fact n = n*fact (n -1)
  5. 5. Чисто функциональный язык (purely functional) Представьте что все const
  6. 6. Чисто функциональный язык (purely functional) f (x) = ax2 + bx + c Решить для x при f (x) = 0 ∆ = b2 − 4ac x1,2 = −b ± √ ∆ 2a
  7. 7. Чисто функциональный язык (purely functional) module Discriminant where solveQuadratic a b c = let d = b*b - 4*a*c in if d < 0 then [] else if d == 0 then [-b/(2*a)] else [-b + (sqrt d)/(2*a), -b - (sqrt d)/(2*a)]
  8. 8. Чисто функциональный язык (purely functional) d = b * b - 4 * a * c
  9. 9. Списки (lists) • [] - пустой список • [1, 2, 42] - список с тремя элементами • [[], [1], [1, 2], [1, 2, 42]] - список списков
  10. 10. Списки (lists) • [1, 2 .. 5] = [1, 2, 3, 4, 5] • [1, 2 .. ] • [1 .. ]
  11. 11. Списки (lists) Добавление в список 42:[] [42] 8:[42] [8 ,42]
  12. 12. Списки (lists) Сложность операций length - O(n) Проверка на пустой список: null Не используйте length ls == 0 Привет C++ и .empty() из STL
  13. 13. Функции первого порядка Функции могут передаваться в качестве параметров функций odd 1 True filter odd [1, 2, 3] [1, 3]
  14. 14. Язык с ленивой моделью вычислений (lazy) filter odd [1, 2, 3, 4, 5] filter odd [1, 2 .. 5] [1, 3, 5]
  15. 15. Язык с ленивой моделью вычислений (lazy) filter odd [1 ..] take 3 (filter odd [1 ..]) [1, 3, 5]
  16. 16. Язык со статической типизацией (static typing) Проверка типов на этапе компиляции
  17. 17. Язык со строгой типизацией (strong typing) Явные приведения между всеми типами Int, Float, ...
  18. 18. С чего начать http://www.haskell.org/ Компилятор http://www.haskell.org/ghc/
  19. 19. Математическая нотация Множества A и B Функция F F : A → B
  20. 20. Нотация типов в Haskell Переменные типов: a и b В данном случае на типы не накладывается никаких ограничений Функция f f :: a -> b
  21. 21. Примеры Переменные типов: a, b и c Функция f f :: a -> b -> c Списки f :: a -> [a]
  22. 22. Функции первого порядка filter :: (a -> Bool) -> [a] -> [a] map :: (a -> b) -> [a] -> [b] foldr :: (a -> b -> b) -> b -> [a] -> b
  23. 23. Логика типов Определение тела функции по ее типу f :: a -> a
  24. 24. Логика типов Определение тела функции по ее типу f :: a -> a Возможное решение f a = a f = id id 42 42
  25. 25. Логика типов Какие возможны реализации? f :: a -> [a]
  26. 26. Выведение типов Для функции fact module Fact where fact 0 = 1 fact n = n*fact (n -1) получим тип fact :: (Eq a, Num a) => a -> a
  27. 27. Выведение типов Все типы функций могут быть выведены автоматически на этапе компиляции Явное указание типа может помочь в отладке Скомпилировалось – работает (joke)
  28. 28. Выведение типов C++11 добавляет выведение типа переменных – auto auto value = 42; auto value = 1 + 2; auto value = f(42); C++14 добавляет выведение типа, возвращаемого функцией – auto auto foobar(int value) { return value + 1; }
  29. 29. Алгебраические типы данных (Algebraic Data Types) Наиболее общий составной тип, представляющий собой тип-сумму из типов-произведений (wikipedia)
  30. 30. Тип с одним параметром Множество A Переменная типа a data Name a = Constructor a
  31. 31. Тип с несколькими параметрами Множества T, A и B Переменные типа a и b data Name a b = Constructor a b тип-произведение T = A × B
  32. 32. Тип с несколькими конструкторами Множества T и A Переменная типа a data Name a = ContructorF a | ContructorS a тип-сумма Af = {(x, 1) : x ∈ A} As = {(x, 2) : x ∈ A} T = Af ∪ As
  33. 33. Все вместе Множества T, A, B Переменные типа a и b data Name a b = ContructorF a b | ContructorS a сумма произведений Af = {(x, 1) : x ∈ A × B} As = {(x, 2) : x ∈ A} T = Af ∪ As
  34. 34. Дизъюнктное объединение (Disjoint union) i∈I {(x, i) : x ∈ Ai }
  35. 35. Зачем • Формальное обощение: enum, struct, union • Сопоставление параметров функций по шаблону
  36. 36. Параметры функций data State a b = First a | Second b | Third a b handle (First s) v = Second (f s) handle (Second s) v = First s handle (Third s t) v = Third s (f t v)
  37. 37. enum data Bool = True | False data Color = Red | Green | Blue enum Bool { TRUE , FALSE };
  38. 38. struct data State a b = St a b struct State { int a; int b; };
  39. 39. union data State a b = First a b | Second a union State { struct { int a; int b; } first; struct { int a; } second; };
  40. 40. Рекурсивные типы данных Бинарное дерево module Tree where data Tree a = Leaf | Node (Tree a) a (Tree a) sumTree Leaf = 0 sumTree (Node left v right) = sumTree left + v + sumTree right import Tree main = putStrLn $ show (sumTree (Node (Node (Leaf) 2 (Node (Leaf) 3 (Leaf))) 1 ( Leaf))) 6
  41. 41. Списки List a = [] | (:) a (List a)
  42. 42. Полиморфизм Позволяет строить суждения о типах зная только класс этих типов Класс описывает функции, реализуемые типом
  43. 43. Typeclasses Моноид - множество с заданной на нем ассоциативной бинарной операцией и нейтральным элементом. (a · b) · c = a · (b · c) a · e = a Пример: целые числа с операцией умножения. Что насчет чисел с плавающей запятой?
  44. 44. Typeclasses module Monoid where class Monoid a where binop :: a -> a -> a identity :: a twice :: Monoid a => a -> a twice a = binop a a
  45. 45. Typeclasses “In fact, trolls traditionally count like this: one, two, three . . . many, and people assume this means they can have no grasp of higher numbers.” – Men at Arms, Terry Pratchett
  46. 46. Typeclasses module TrollNum(TrollNum (..) , plus , binop , identity) where import Monoid data TrollNum = Zero | One | Two | Three | Many deriving Show plus :: TrollNum -> TrollNum -> TrollNum plus a b = fromNum (toNum a + toNum b) instance Monoid TrollNum where binop = plus identity = Zero toNum Zero = 0 toNum One = 1 toNum Two = 2 toNum Three = 3 toNum Many = 4 fromNum 0 = Zero fromNum 1 = One fromNum 2 = Two fromNum 3 = Three fromNum _ = Many
  47. 47. Typeclasses import Monoid import TrollNum main = putStrLn $ show $ twice Two Many
  48. 48. Операторы Среднее арифметическое module Ops where (-|-) a b = (a + b)/2
  49. 49. Pointfree style Функции f (x), g(x) и z(x) z(x) = f (g(x)) z = f . g (.) :: (b -> c) -> (a -> b) -> a -> c
  50. 50. Pointfree style Функция, прибавляющая 1 к переданному значению addOne v = v + 1 addOne v = (+) v 1 addOne v = (+) 1 v addOne = (+) 1 ((+) 1) :: Num a => a -> a
  51. 51. Pointfree style Найти длину самого длинного слова в строке module LongestWord where longestWord = (foldr max 0) . (map length) . words Привет map-reduce
  52. 52. Понятие Это абстракция линейной цепочки связанных вычислений. Её основное назначение - инкапсуляция функций с побочным эффектом от чистых функций, а точнее их выполнений от вычислений (wikipedia).
  53. 53. Info class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a fail :: String -> m a
  54. 54. Общий шаблон • Тип с одним параметром m • Получение значения (bind): функция (»=) :: m a -> (a -> m b) -> m b • Инъекция значения (inject): функция return :: a -> m a
  55. 55. Monad
  56. 56. IO Как возможно IO в системе без побочных эффектов? IO monad
  57. 57. Снова факториал Хвостовая рекурсия module XFact where xfact n = xfact ’ 1 n where xfact ’ v 0 = v xfact ’ v n = xfact ’ (v*n) (n-1)
  58. 58. Выведение типов Модульная арифметика module ModInt where newtype ModInt = ModInt { fromModInt :: Int } deriving (Show) instance Num ModInt where (+) (ModInt a) (ModInt b) = ModInt ((a + b) ‘mod ‘ 23) (*) (ModInt a) (ModInt b) = ModInt ((a * b) ‘mod ‘ 23) abs (ModInt a) = ModInt (abs a) signum (ModInt a) = ModInt (signum a) fromInteger v = ModInt (fromInteger v ‘mod ‘ 23) import ModInt pow a 0 = 1 pow a b = a * pow a (b-1) main = putStrLn $ show $ fromModInt $ pow 2 5 9
  59. 59. DSL import Fuzz import DumbFuzzer authRequest = "AUTH" ‘wait ‘ authResponses getRequest = "GET" ‘wait ‘ getResponses authResponses = ("AUTHED" |-> getRequest) // (other (report 0)) getResponses = ("200␣OK" |-> report 1) // ("418␣I’m␣a␣teapot" |-> report 42) // (other (report 0)) main = do r <- fuzz DumbFuzzer authRequest putStrLn $ show r
  60. 60. Fuzz I module Fuzz(wait , report , (|->), (//) , other , fuzz , Fuzzer (..)) where data Response r = Response (Msg , Request r) | Other (Request r) data Request r = Send Msg [Response r] | Report r report :: r -> Request r report r = Report r wait :: Msg -> [Response r] -> Request r wait message reactions = Send message reactions other :: Request r -> [Response r] other response = [Other response] (|->) :: Msg -> Request r -> [Response r] (|->) message action = [Response (message , action)] (//) :: [Response r] -> [Response r] -> [Response r] (//) a b = a ++ b fuzz :: Fuzzer f => f -> Request r -> IO r fuzz f (Send msg responses) = do r <- send f msg next f r responses fuzz f (Report r) = return r class Fuzzer f where send :: f -> Msg -> IO Msg
  61. 61. Fuzz II next f _ [Other request] = fuzz f request next f resp (( Other request):rs) = next f resp (rs ++ [Other request ]) next f resp (( Response (msg , request)):rs) | resp == msg = fuzz f request | otherwise = next f resp rs type Msg = String
  62. 62. Fuzzer module DumbFuzzer where import Fuzz data DumbFuzzer = DumbFuzzer instance Fuzzer DumbFuzzer where send _ m = do putStrLn m getLine
  63. 63. Литература • Real World Haskell by Bryan O’Sullivan, John Goerzen, and Don Stewart • The Haskell Road to Logic, Math and Programming by Kees Doets and Jan van Eijck • Parallel and Concurrent Programming in Haskell by Simon Marlow • Haskell Beats C Using Generalized Stream Fusion by Geoffrey Mainland, Roman Leshchinskiy, and Simon Peyton Jones (paper)

×