Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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.

502 views

Published on

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

Published in: Technology
  • Be the first to comment

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)

×