haskell type system with dzmitry ivashnev

64
Haskell Type System Ивашнёв Дмитрий email: [email protected] jabber: [email protected] 25 апреля 2014 г.

Upload: sergey-tihon

Post on 28-Jun-2015

256 views

Category:

Technology


4 download

DESCRIPTION

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

TRANSCRIPT

Page 1: Haskell Type System with Dzmitry Ivashnev

Haskell Type System

Ивашнёв Дмитрийemail: [email protected]

jabber: [email protected]

25 апреля 2014 г.

Page 2: Haskell Type System with Dzmitry Ivashnev

Парадигма

• Функциональный язык (functional)• Чисто функциональный язык (purely functional)• Язык с ленивой моделью вычислений (lazy)• Язык со статической типизацией (static typing)• Язык со строгой типизацией (strong typing)

Page 3: Haskell Type System with Dzmitry Ivashnev

Функциональный язык (functional)

fact(n) =

{1 if n = 0n × fact(n − 1) otherwise

Page 4: Haskell Type System with Dzmitry Ivashnev

Функциональный язык (functional)

module Factwhere

fact 0 = 1fact n = n*fact (n-1)

Page 5: Haskell Type System with Dzmitry Ivashnev

Чисто функциональный язык (purelyfunctional)

Представьте что все const

Page 6: Haskell Type System with Dzmitry Ivashnev

Чисто функциональный язык (purelyfunctional)

f (x) = ax2 + bx + c

Решить для x при f (x) = 0

∆ = b2 − 4ac

x1,2 =−b ±

√∆

2a

Page 7: Haskell Type System with Dzmitry Ivashnev

Чисто функциональный язык (purelyfunctional)

module Discriminantwhere

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)]

Page 8: Haskell Type System with Dzmitry Ivashnev

Чисто функциональный язык (purelyfunctional)

d = b * b - 4 * a * c

Page 9: Haskell Type System with Dzmitry Ivashnev

Списки (lists)

• [] - пустой список• [1, 2, 42] - список с тремя элементами• [[], [1], [1, 2], [1, 2, 42]] - список списков

Page 10: Haskell Type System with Dzmitry Ivashnev

Списки (lists)

• [1, 2 .. 5] = [1, 2, 3, 4, 5]• [1, 2 .. ]• [1 .. ]

Page 11: Haskell Type System with Dzmitry Ivashnev

Списки (lists)

Добавление в список42:[][42]

8:[42][8,42]

Page 12: Haskell Type System with Dzmitry Ivashnev

Списки (lists)

Сложность операцийlength - O(n)Проверка на пустой список: nullНе используйте length ls == 0Привет C++ и .empty() из STL

Page 13: Haskell Type System with Dzmitry Ivashnev

Функции первого порядка

Функции могут передаваться в качестве параметров функцийodd 1True

filter odd [1, 2, 3][1, 3]

Page 14: Haskell Type System with Dzmitry Ivashnev

Язык с ленивой моделью вычислений(lazy)

filter odd [1, 2, 3, 4, 5]

filter odd [1, 2 .. 5]

[1, 3, 5]

Page 15: Haskell Type System with Dzmitry Ivashnev

Язык с ленивой моделью вычислений(lazy)

filter odd [1 ..]

take 3 (filter odd [1 ..])

[1, 3, 5]

Page 16: Haskell Type System with Dzmitry Ivashnev

Язык со статической типизацией (statictyping)

Проверка типов на этапе компиляции

Page 17: Haskell Type System with Dzmitry Ivashnev

Язык со строгой типизацией (strongtyping)

Явные приведения между всеми типамиInt, Float, ...

Page 18: Haskell Type System with Dzmitry Ivashnev

С чего начать

http://www.haskell.org/Компиляторhttp://www.haskell.org/ghc/

Page 19: Haskell Type System with Dzmitry Ivashnev

Математическая нотация

Множества A и BФункция F

F : A→ B

Page 20: Haskell Type System with Dzmitry Ivashnev

Нотация типов в Haskell

Переменные типов: a и bВ данном случае на типы не накладывается никакихограниченийФункция f

f :: a -> b

Page 21: Haskell Type System with Dzmitry Ivashnev

Примеры

Переменные типов: a, b и cФункция f

f :: a -> b -> c

Спискиf :: a -> [a]

Page 22: Haskell Type System with Dzmitry Ivashnev

Функции первого порядка

filter :: (a -> Bool) -> [a] -> [a]map :: (a -> b) -> [a] -> [b]foldr :: (a -> b -> b) -> b -> [a] -> b

Page 23: Haskell Type System with Dzmitry Ivashnev

Логика типов

Определение тела функции по ее типуf :: a -> a

Page 24: Haskell Type System with Dzmitry Ivashnev

Логика типов

Определение тела функции по ее типуf :: a -> a

Возможное решениеf a = a

f = id

id 4242

Page 25: Haskell Type System with Dzmitry Ivashnev

Логика типов

Какие возможны реализации?f :: a -> [a]

Page 26: Haskell Type System with Dzmitry Ivashnev

Выведение типов

Для функции factmodule Factwhere

fact 0 = 1fact n = n*fact (n-1)

получим типfact :: (Eq a, Num a) => a -> a

Page 27: Haskell Type System with Dzmitry Ivashnev

Выведение типов

Все типы функций могут быть выведены автоматически наэтапе компиляцииЯвное указание типа может помочь в отладкеСкомпилировалось – работает (joke)

Page 28: Haskell Type System with Dzmitry Ivashnev

Выведение типов

C++11 добавляет выведение типа переменных – autoauto value = 42;auto value = 1 + 2;auto value = f(42);

C++14 добавляет выведение типа, возвращаемого функцией –auto

auto foobar(int value){

return value + 1;}

Page 29: Haskell Type System with Dzmitry Ivashnev

Алгебраические типы данных (AlgebraicData Types)

Наиболее общий составной тип, представляющий собойтип-сумму из типов-произведений (wikipedia)

Page 30: Haskell Type System with Dzmitry Ivashnev

Тип с одним параметром

Множество AПеременная типа a

data Name a = Constructor a

Page 31: Haskell Type System with Dzmitry Ivashnev

Тип с несколькими параметрами

Множества T, A и BПеременные типа a и b

data Name a b = Constructor a b

тип-произведениеT = A× B

Page 32: Haskell Type System with Dzmitry Ivashnev

Тип с несколькими конструкторами

Множества T и AПеременная типа a

data Name a = ContructorF a | ContructorS a

тип-суммаAf = {(x , 1) : x ∈ A}

As = {(x , 2) : x ∈ A}

T = Af ∪ As

Page 33: Haskell Type System with Dzmitry Ivashnev

Все вместе

Множества 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

Page 34: Haskell Type System with Dzmitry Ivashnev

Дизъюнктное объединение (Disjointunion)

⋃i∈I{(x , i) : x ∈ Ai}

Page 35: Haskell Type System with Dzmitry Ivashnev

Зачем

• Формальное обощение: enum, struct, union• Сопоставление параметров функций по шаблону

Page 36: Haskell Type System with Dzmitry Ivashnev

Параметры функций

data State a b = First a | Second b | Third a b

handle (First s) v = Second (f s)handle (Second s) v = First shandle (Third s t) v = Third s (f t v)

Page 37: Haskell Type System with Dzmitry Ivashnev

enum

data Bool = True | Falsedata Color = Red | Green | Blue

enum Bool{

TRUE ,FALSE

};

Page 38: Haskell Type System with Dzmitry Ivashnev

struct

data State a b = St a b

struct State{

int a;int b;

};

Page 39: Haskell Type System with Dzmitry Ivashnev

union

data State a b = First a b | Second a

union State{

struct{

int a;int b;

} first;struct{

int a;} second;

};

Page 40: Haskell Type System with Dzmitry Ivashnev

Рекурсивные типы данных

Бинарное деревоmodule Treewhere

data Tree a = Leaf | Node (Tree a) a (Tree a)

sumTree Leaf = 0sumTree (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

Page 41: Haskell Type System with Dzmitry Ivashnev

Списки

List a = [] | (:) a (List a)

Page 42: Haskell Type System with Dzmitry Ivashnev

Полиморфизм

Позволяет строить суждения о типах зная только класс этихтиповКласс описывает функции, реализуемые типом

Page 43: Haskell Type System with Dzmitry Ivashnev

Typeclasses

Моноид - множество с заданной на нем ассоциативнойбинарной операцией и нейтральным элементом.

(a · b) · c = a · (b · c)

a · e = a

Пример: целые числа с операцией умножения.Что насчет чисел с плавающей запятой?

Page 44: Haskell Type System with Dzmitry Ivashnev

Typeclasses

module Monoidwhere

class Monoid a wherebinop :: a -> a -> aidentity :: a

twice :: Monoid a => a -> atwice a = binop a a

Page 45: Haskell Type System with Dzmitry Ivashnev

Typeclasses

“In fact, trolls traditionally count like this: one, two, three . . .many, and people assume this means they can have no grasp ofhigher numbers.” – Men at Arms, Terry Pratchett

Page 46: Haskell Type System with Dzmitry Ivashnev

Typeclasses

module TrollNum(TrollNum (..), plus , binop , identity)where

import Monoid

data TrollNum = Zero | One | Two | Three | Manyderiving Show

plus :: TrollNum -> TrollNum -> TrollNumplus a b = fromNum (toNum a + toNum b)

instance Monoid TrollNum wherebinop = plusidentity = Zero

toNum Zero = 0toNum One = 1toNum Two = 2toNum Three = 3toNum Many = 4

fromNum 0 = ZerofromNum 1 = OnefromNum 2 = TwofromNum 3 = ThreefromNum _ = Many

Page 47: Haskell Type System with Dzmitry Ivashnev

Typeclasses

import Monoidimport TrollNum

main = putStrLn $ show $ twice Two

Many

Page 48: Haskell Type System with Dzmitry Ivashnev

Операторы

Среднее арифметическоеmodule Opswhere

(-|-) a b = (a + b)/2

Page 49: Haskell Type System with Dzmitry Ivashnev

Pointfree style

Функции f (x), g(x) и z(x)z(x) = f (g(x))

z = f . g(.) :: (b -> c) -> (a -> b) -> a -> c

Page 50: Haskell Type System with Dzmitry Ivashnev

Pointfree style

Функция, прибавляющая 1 к переданному значениюaddOne v = v + 1addOne v = (+) v 1addOne v = (+) 1 vaddOne = (+) 1((+)1) :: Num a => a -> a

Page 51: Haskell Type System with Dzmitry Ivashnev

Pointfree style

Найти длину самого длинного слова в строкеmodule LongestWordwhere

longestWord = (foldr max 0) . (map length) . words

Привет map-reduce

Page 52: Haskell Type System with Dzmitry Ivashnev
Page 53: Haskell Type System with Dzmitry Ivashnev

Понятие

Это абстракция линейной цепочки связанных вычислений. Еёосновное назначение - инкапсуляция функций с побочнымэффектом от чистых функций, а точнее их выполнений отвычислений (wikipedia).

Page 54: Haskell Type System with Dzmitry Ivashnev

Info

class Monad m where(>>=) :: m a -> (a -> m b) -> m b(>>) :: m a -> m b -> m breturn :: a -> m afail :: String -> m a

Page 55: Haskell Type System with Dzmitry Ivashnev

Общий шаблон

• Тип с одним параметром m• Получение значения (bind):функция (»=) :: m a -> (a -> m b) -> m b

• Инъекция значения (inject):функция return :: a -> m a

Page 56: Haskell Type System with Dzmitry Ivashnev

Monad

Page 57: Haskell Type System with Dzmitry Ivashnev

IO

Как возможно IO в системе без побочных эффектов?IO monad

Page 58: Haskell Type System with Dzmitry Ivashnev

Снова факториал

Хвостовая рекурсияmodule XFactwhere

xfact n = xfact ’ 1 nwhere

xfact ’ v 0 = vxfact ’ v n = xfact ’ (v*n) (n-1)

Page 59: Haskell Type System with Dzmitry Ivashnev

Выведение типов

Модульная арифметикаmodule ModIntwhere

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 = 1pow a b = a * pow a (b-1)

main = putStrLn $ show $ fromModInt $ pow 2 5

9

Page 60: Haskell Type System with Dzmitry Ivashnev

DSL

import Fuzzimport DumbFuzzer

authRequest = "AUTH" ‘wait ‘ authResponsesgetRequest = "GET" ‘wait ‘ getResponsesauthResponses = ("AUTHED" |-> getRequest) // (other (report 0))getResponses = ("200␣OK" |-> report 1) // ("418␣I’m␣a␣teapot" |-> report 42) //

(other (report 0))

main = dor <- fuzz DumbFuzzer authRequestputStrLn $ show r

Page 61: Haskell Type System with Dzmitry Ivashnev

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 rreport r = Report r

wait :: Msg -> [Response r] -> Request rwait 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 rfuzz f (Send msg responses) = do

r <- send f msgnext f r responses

fuzz f (Report r) = return r

class Fuzzer f wheresend :: f -> Msg -> IO Msg

Page 62: Haskell Type System with Dzmitry Ivashnev

Fuzz II

next f _ [Other request] = fuzz f requestnext 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

Page 63: Haskell Type System with Dzmitry Ivashnev

Fuzzer

module DumbFuzzerwhere

import Fuzz

data DumbFuzzer = DumbFuzzer

instance Fuzzer DumbFuzzer wheresend _ m = do

putStrLn mgetLine

Page 64: Haskell Type System with Dzmitry Ivashnev

Литература

• Real World Haskell by Bryan O’Sullivan, John Goerzen, andDon Stewart

• The Haskell Road to Logic, Math and Programming by KeesDoets and Jan van Eijck

• Parallel and Concurrent Programming in Haskell by SimonMarlow

• Haskell Beats C Using Generalized Stream Fusion by GeoffreyMainland, Roman Leshchinskiy, and Simon Peyton Jones(paper)