• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Haskell Type System with Dzmitry Ivashnev.
 

Haskell Type System with Dzmitry Ivashnev.

on

  • 105 views

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

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

Statistics

Views

Total Views
105
Views on SlideShare
105
Embed Views
0

Actions

Likes
1
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Haskell Type System with Dzmitry Ivashnev. Haskell Type System with Dzmitry Ivashnev. Presentation Transcript

    • Haskell Type System Ивашнёв Дмитрий email: 0xff0x666@gmail.com jabber: xffox@headcounter.org 25 апреля 2014 г.
    • Парадигма • Функциональный язык (functional) • Чисто функциональный язык (purely functional) • Язык с ленивой моделью вычислений (lazy) • Язык со статической типизацией (static typing) • Язык со строгой типизацией (strong typing)
    • Функциональный язык (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 ± √ ∆ 2a
    • Чисто функциональный язык (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)]
    • Чисто функциональный язык (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++ и .empty() из STL
    • Функции первого порядка Функции могут передаваться в качестве параметров функций 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
    • Примеры Переменные типов: 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 -> [a] -> 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) => a -> a
    • Выведение типов Все типы функций могут быть выведены автоматически на этапе компиляции Явное указание типа может помочь в отладке Скомпилировалось – работает (joke)
    • Выведение типов C++11 добавляет выведение типа переменных – auto auto value = 42; auto value = 1 + 2; auto value = f(42); C++14 добавляет выведение типа, возвращаемого функцией – auto auto foobar(int value) { return value + 1; }
    • Алгебраические типы данных (Algebraic Data Types) Наиболее общий составной тип, представляющий собой тип-сумму из типов-произведений (wikipedia)
    • Тип с одним параметром Множество A Переменная типа a data Name a = Constructor a
    • Тип с несколькими параметрами Множества T, A и B Переменные типа a и b data Name a b = Constructor a b тип-произведение T = A × B
    • Тип с несколькими конструкторами Множества T и A Переменная типа a data Name a = ContructorF a | ContructorS a тип-сумма Af = {(x, 1) : x ∈ A} As = {(x, 2) : x ∈ A} T = Af ∪ As
    • Все вместе Множества 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
    • Дизъюнктное объединение (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 = First s handle (Third s t) v = Third s (f t 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 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
    • Списки List a = [] | (:) a (List a)
    • Полиморфизм Позволяет строить суждения о типах зная только класс этих типов Класс описывает функции, реализуемые типом
    • Typeclasses Моноид - множество с заданной на нем ассоциативной бинарной операцией и нейтральным элементом. (a · b) · c = a · (b · c) a · e = a Пример: целые числа с операцией умножения. Что насчет чисел с плавающей запятой?
    • Typeclasses module Monoid where class Monoid a where binop :: a -> a -> a identity :: a twice :: Monoid a => a -> a twice a = binop a a
    • 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
    • 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
    • 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 addOne = (+) 1 ((+) 1) :: Num a => a -> a
    • Pointfree style Найти длину самого длинного слова в строке module LongestWord where longestWord = (foldr max 0) . (map length) . words Привет map-reduce
    • Понятие Это абстракция линейной цепочки связанных вычислений. Её основное назначение - инкапсуляция функций с побочным эффектом от чистых функций, а точнее их выполнений от вычислений (wikipedia).
    • 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
    • Общий шаблон • Тип с одним параметром m • Получение значения (bind): функция (»=) :: m a -> (a -> m b) -> m b • Инъекция значения (inject): функция return :: a -> m a
    • Monad
    • IO Как возможно IO в системе без побочных эффектов? IO monad
    • Снова факториал Хвостовая рекурсия module XFact where xfact n = xfact ’ 1 n where xfact ’ v 0 = v xfact ’ v n = xfact ’ (v*n) (n-1)
    • Выведение типов Модульная арифметика 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
    • 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
    • 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
    • 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
    • Fuzzer module DumbFuzzer where import Fuzz data DumbFuzzer = DumbFuzzer instance Fuzzer DumbFuzzer where send _ m = do putStrLn m getLine
    • Литература • 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)