Declarative authorization in REST services in SharePoint with F# and ServiceS...
Haskell Type System with Dzmitry Ivashnev.
1. Haskell Type System
Ивашнёв Дмитрий
email: 0xff0x666@gmail.com
jabber: xffox@headcounter.org
25 апреля 2014 г.
2. Парадигма
• Функциональный язык (functional)
• Чисто функциональный язык (purely functional)
• Язык с ленивой моделью вычислений (lazy)
• Язык со статической типизацией (static typing)
• Язык со строгой типизацией (strong typing)
6. Чисто функциональный язык (purely
functional)
f (x) = ax2
+ bx + c
Решить для x при f (x) = 0
∆ = b2
− 4ac
x1,2 =
−b ±
√
∆
2a
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)]
26. Выведение типов
Для функции fact
module Fact
where
fact 0 = 1
fact n = n*fact (n -1)
получим тип
fact :: (Eq a, Num a) => a -> a
27. Выведение типов
Все типы функций могут быть выведены автоматически на
этапе компиляции
Явное указание типа может помочь в отладке
Скомпилировалось – работает (joke)
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. Алгебраические типы данных (Algebraic
Data Types)
Наиболее общий составной тип, представляющий собой
тип-сумму из типов-произведений (wikipedia)
30. Тип с одним параметром
Множество A
Переменная типа a
data Name a = Constructor a
31. Тип с несколькими параметрами
Множества T, A и B
Переменные типа a и b
data Name a b = Constructor a b
тип-произведение
T = A × B
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. Все вместе
Множества 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
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. enum
data Bool = True | False
data Color = Red | Green | Blue
enum Bool
{
TRUE ,
FALSE
};
39. union
data State a b = First a b | Second a
union State
{
struct
{
int a;
int b;
} first;
struct
{
int a;
} second;
};
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
43. Typeclasses
Моноид - множество с заданной на нем ассоциативной
бинарной операцией и нейтральным элементом.
(a · b) · c = a · (b · c)
a · e = a
Пример: целые числа с операцией умножения.
Что насчет чисел с плавающей запятой?
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. 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
49. Pointfree style
Функции f (x), g(x) и z(x)
z(x) = f (g(x))
z = f . g
(.) :: (b -> c) -> (a -> b) -> a -> c
50. Pointfree style
Функция, прибавляющая 1 к переданному значению
addOne v = v + 1
addOne v = (+) v 1
addOne v = (+) 1 v
addOne = (+) 1
((+) 1) :: Num a => a -> a
51. Pointfree style
Найти длину самого длинного слова в строке
module LongestWord
where
longestWord = (foldr max 0) . (map length) . words
Привет map-reduce
52.
53. Понятие
Это абстракция линейной цепочки связанных вычислений. Её
основное назначение - инкапсуляция функций с побочным
эффектом от чистых функций, а точнее их выполнений от
вычислений (wikipedia).
54. 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
55. Общий шаблон
• Тип с одним параметром m
• Получение значения (bind):
функция (»=) :: m a -> (a -> m b) -> m b
• Инъекция значения (inject):
функция return :: a -> m a
59. Выведение типов
Модульная арифметика
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
61. 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
62. 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
64. Литература
• 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)