27

Евгений Курбацкий. Зачем нужны зависимые типы

Embed Size (px)

Citation preview

Page 1: Евгений Курбацкий. Зачем нужны зависимые типы

Çà÷åì íóæíû çàâèñèìûå òèïû

Åâãåíèé Êóðáàöêèé

JetBrains

2013

1 / 27

Page 2: Евгений Курбацкий. Зачем нужны зависимые типы

Çà÷åì íóæíû çàâèñèìûå òèïû

÷òî òàêîå çàâèñèìûé òèï

ñïèñêè ôèêñèðîâàííîé äëèííû

áåçîïàñíûé printf

êîíñòðóêòèâíàÿ ìàòåìàòèêà

ñòàòè÷åñêèå ïðîâåðêè

2 / 27

Page 3: Евгений Курбацкий. Зачем нужны зависимые типы

Çàâèñèìàÿ ôóíêöèÿ

(x : A) → B(x)

f : (x : Bool) -> (if x then String else Int)f True = "42"f False = 42

3 / 27

Page 4: Евгений Курбацкий. Зачем нужны зависимые типы

Òèïû òèïîâ

òèï ÿâëÿåòñÿ âûðàæåíèåì5 : Int

Int : Type

Int -> Int : Type

5 : (if False then String else Int)

(x : Bool) ->(if x then String else Int) : Type

"What?" : if (isPrime 2147483647) thenString else Int

4 / 27

Page 5: Евгений Курбацкий. Зачем нужны зависимые типы

Ïðîâåðêà òèïîâ

Òîòàëüíûå ôóíêöèè

ôóíêöèÿ âñåãäà çàâåðøàåòñÿ

ôóíêöèÿ âñåãäà âîçâðàùàåò çíà÷åíèå

5 / 27

Page 6: Евгений Курбацкий. Зачем нужны зависимые типы

Idris

ïîääåðæèâàåò çàâèñèìûå òèïû

ñèíòàêñèñ ïîõîæ íà Haskell

�íå ëåíèâûå� âû÷èñëåíèÿ

àêòèâíî ðàçðàáàòûâàåòñÿ

â äîêëàäå èñïîëüçîâàííà âåðñèÿ 0.9.8

6 / 27

Page 7: Евгений Курбацкий. Зачем нужны зависимые типы

Íàòóðàëüíûå ÷èñëà

data Nat : Type where

Z : Nat

S : Nat -> Nat

(+) : Nat -> Nat -> Nat

Z + y = y

(S k) + y = S (k + y)

7 / 27

Page 8: Евгений Курбацкий. Зачем нужны зависимые типы

Ñïèñêè ôèêñèðîâàííîé äëèííû

data List : Type -> Type whereNil : List a(::) : a -> List a -> List a

data Vect : Type -> Nat -> Type whereNil : Vect a Z(::) : a -> Vect a k -> Vect a (S k)

app : Vect a n -> Vect a m -> Vect a (n + m)app Nil ys = ysapp (x :: xs) ys = x :: app xs ys

8 / 27

Page 9: Евгений Курбацкий. Зачем нужны зависимые типы

Ñïèñêè ôèêñèðîâàííîé äëèííû

data Vect : Type -> Nat -> Type whereNil : Vect a Z(::) : a -> Vect a k -> Vect a (S k)

Nil : Vect Int Z(1 :: 2 :: 3 :: Nil) : Vect Int (S S S Z)

IntVect : Nat -> TypeIntVect = Vect Int

(1 :: 2 :: Nil) : IntVect (S S Z)

9 / 27

Page 10: Евгений Курбацкий. Зачем нужны зависимые типы

Ñïèñêè ôèêñèðîâàííîé äëèííû

data Vect : Type -> Nat -> Type whereNil : Vect a Z(::) : a -> Vect a k -> Vect a (S k)

head : Vect a (S k) -> ahead (h :: t) = h

head (1 :: 2 :: 4 :: Nil)head Nil

defaultHead : Vect a k -> a -> adefaultHead Nil default = default

defaultHead v _ = head v

10 / 27

Page 11: Евгений Курбацкий. Зачем нужны зависимые типы

Printf

sprintf "Simple!!!"

sprintf "Hello %s!!!" "world"

sprintf "Answer is %d" 42

sprintf "Mistake %s %d" 42 "world"

sprintf "Forgot %d"

sprintf "Too much %d" 1 2

11 / 27

Page 12: Евгений Курбацкий. Зачем нужны зависимые типы

Printf

data Format = End |FMInt Format |FMString Format |FMChar Char Format

parse : List Char -> Formatparse Nil = Endparse ('%'::'d'::cs) = FMInt (parse cs)parse ('%'::'s'::cs) = FMString (parse cs)parse (c::cs) = FMChar c (parse cs)

12 / 27

Page 13: Евгений Курбацкий. Зачем нужны зависимые типы

ToType : Format -> TypeToType End = StringToType (FMInt rest) = Int -> ToType restToType (FMString rest) = String -> ToType restToType (FMChar c rest) = ToType rest

13 / 27

Page 14: Евгений Курбацкий. Зачем нужны зависимые типы

sprintf : (f: String) ->ToType (parse (unpack f))

sprintf fmt = prt (parse (unpack f)) Nil

prt : (f: Format) -> List Char -> ToType fprt End acc =

pack accprt (FMInt r) acc =

\i: Int => prt r (acc ++ (unpack (show i)))prt (FMString r) acc =

\s: String => prt r (acc ++ (unpack s))prt (FMChar c r) acc =

prt r (acc ++ [c])

14 / 27

Page 15: Евгений Курбацкий. Зачем нужны зависимые типы

Çàâèñèìàÿ ïàðà

d : (x : Bool ** if x then String else Int)d = (False ** 42)

15 / 27

Page 16: Евгений Курбацкий. Зачем нужны зависимые типы

Êîíñòðóêòèâíàÿ ìàòåìàòèêà

data Or : a -> b -> Type whereInl : a -> Or a bInr : b -> Or a b

data And : a -> b -> Type wheremkAnd : a -> b -> And

data True : TypemkTrue : True

data _|_ : Type where

Not : Type -> TypeNot a = a -> _|_

16 / 27

Page 17: Евгений Курбацкий. Зачем нужны зависимые типы

Êîíñòðóêòèâíàÿ ìàòåìàòèêà

Ìàòåìàòèêà Òèïû

Òåîðåìà ÒèïÄîêçàòåëüñòâî Òåðì

True True (Unit)False _|_

A → B A -> B

A ∧ B And A B (Ïàðà)A ∨ B Or A B (Either)¬A A -> _|_

∀x ∈A B(x) (x : A) -> B x

∃x ∈A B(x) (x : A ** B x)Èíäóêöèÿ Ðåêóðñèÿ

17 / 27

Page 18: Евгений Курбацкий. Зачем нужны зависимые типы

Ïðèìåð

A ∨ B → B ∨ A

Or a b -> Or b a

lemma1 : Or a b -> Or b alemma1 (Inl av) = (Inr av)lemma1 (Inr bv) = (Inl bv)

18 / 27

Page 19: Евгений Курбацкий. Зачем нужны зависимые типы

Ïðèìåð

(A → B) → (B → C ) → (A → C )(a -> b) -> (b -> c) -> (a -> c)

lemma2 : (a -> b) -> (b -> c) -> (a -> c)lemma2 f1 f2 = (\x => f2 (f1 x))

19 / 27

Page 20: Евгений Курбацкий. Зачем нужны зависимые типы

Ðàâåíòñâî

data (=) : t -> t -> Type where

refl : (a : t) -> a = a

20 / 27

Page 21: Евгений Курбацкий. Зачем нужны зависимые типы

Ðàâåíòñâî

∀a1∈T , ∀a2∈T , a1 = a2 → a2 = a1

symm : (a1 : t) -> (a2 : t) ->

(a1 = a2) -> (a2 = a1)

symm _ _ (refl a) = (refl a)

21 / 27

Page 22: Евгений Курбацкий. Зачем нужны зависимые типы

Ðàâåíòñâî

∀a∈T , ∀b∈T , ∀p(T ), a = b → p(a) = p(b)

apply : (a : t) -> (b : t) ->(p : t -> t1) ->(a = b) -> (p a) = (p b)

apply _ _ p (refl x) = refl (p x)

22 / 27

Page 23: Евгений Курбацкий. Зачем нужны зависимые типы

Ïðèìåð

(+) : Nat -> Nat -> NatZ + y = y(S k) + y = S (k + y)

∀a, b, c∈N, a + (b + c) = (a + b) + c

assoc : (a : Nat) -> (b : Nat) -> (c : Nat) ->(a + (b + c)) = ((a + b) + c)

assoc Z b c = refl (b + c)assoc (S a) b c = apply (a + (b + c))

((a + b) + c) S (assoc a b c)

23 / 27

Page 24: Евгений Курбацкий. Зачем нужны зависимые типы

Ïðîâåðêè âî âðåìÿ êîìïèëÿöèè

data so : Bool -> Type where

oh : so True

test : Bool

test1 : so test

test1 = oh

test2 : so (2 * 2 == 4)

test2 = oh

testFail : so (2 * 2 == 5)

testFail = oh24 / 27

Page 25: Евгений Курбацкий. Зачем нужны зависимые типы

Ñòàòè÷åñêèå îãðàíè÷åíèÿ

data (<) : Nat -> Nat -> Type wherelessZ : Z < (S k)lessS : k1 < k2 -> (S k1) < (S k2)

Array : Type -> Nat -> Type

get: (Array a sz) -> (i: Nat ** i < sz) -> a

25 / 27

Page 26: Евгений Курбацкий. Зачем нужны зависимые типы

lemma : i < n -> i < (S n)lemma lessZ = lessZlemma (lessS a) = lessS (lemma a)

range2 : (n : Nat) -> (i : Nat) -> i < (S n) ->List (a : Nat ** a < n)

range2 n Z lessZ = []range2 n (S i) (lessS iln) =

(i ** iln) :: (range2 n i (lemma iln))

subList : (n : Nat) -> (i : Nat) -> (i < S n) ->Array a n -> List a

subList n i prf a = map (get a) (range2 n i prf)

26 / 27

Page 27: Евгений Курбацкий. Зачем нужны зависимые типы

Ñïàñèáî çà âíèìàíèå

Âîïðîñû?

27 / 27