35
Dependent Types with Abdulsattar

Dependent Types with Idris

Embed Size (px)

Citation preview

Page 1: Dependent Types with Idris

Dependent Typeswith

Abdulsattar

Page 2: Dependent Types with Idris

Motivationdef first(arr) do List.first arrend

Points of Failure:1. arr is not an array2. arr is null3. arr is empty

Page 3: Dependent Types with Idris

Motivationpublic int first(int[] arr) { return arr[0];}

Points of Failure:1. arr is not an array2. arr is null3. arr is empty

Page 4: Dependent Types with Idris

Motivationfirst :: [Int] -> Int first arr = arr !! 0

Points of Failure:1. arr is not an array2. arr is null3. arr is empty

Page 5: Dependent Types with Idris

Actual Requirement

arr must be an array of at least 1 length

Page 6: Dependent Types with Idris

Problem

first :: [Int] -> Int first arr = arr !! 0

public int first(int[] arr) { return arr[0];}

def first(arr) do List.first arrend

anything → anything (or runtime error)

array or null → int (or runtime error)

array → int (or runtime error)

Page 7: Dependent Types with Idris

Problem

Types don’t capture all the invariants

Page 8: Dependent Types with Idris

Dependent TypesDependent Types allow types to depend on values.e.g. length of a list can be part of the type of the list

Page 9: Dependent Types with Idris

Natural Numbersdata Nat = Z | S Nat

zero = Zone = S Ztwo = S (S Z)…

Page 10: Dependent Types with Idris

Operationsplus : Nat -> Nat -> Natplus Z y = yplus (S k) y = S (plus k y)

0 + y = y(1 + x) + y = 1 + (x + y)

0 ✕ y = 0(1 + x) ✕ y = y + (x ✕ y)

mult : Nat -> Nat -> Natmult Z y = Zmult (S k) y = plus y (mult k y)

Page 11: Dependent Types with Idris

Vectorsdata Vect : Nat -> Type -> Type where Nil : Vect Z a (::) : a -> Vect k a -> Vect (S k) a

zeroVect : Vect 0 Int zeroVect = Nil

oneVect : Vect 1 Int oneVect = 3 :: Nil

threeVect : Vect 3 String threeVect = "I" :: "hope" :: "i'm not confusing you" :: Nil

Page 12: Dependent Types with Idris

Solutionfirst : Vect (S k) a -> afirst (x::xs) = x

Points of Failure:1. arr is not an array2. arr is null3. arr is empty

Page 13: Dependent Types with Idris

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

Page 14: Dependent Types with Idris

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

Error: Expected Vect (n + m) a; Got Vect (n + n) a

* Not actual error message

Page 15: Dependent Types with Idris

Interactive Editing

DEMO

Page 16: Dependent Types with Idris

First-Class TypesA : TypeA = Int

b : Ab = 3

Page 17: Dependent Types with Idris

First-Class TypesA : Bool -> TypeA True = IntA False = String

b : A Trueb = 3

c : A Truec = "Idris"

Page 18: Dependent Types with Idris

Type-safe Printfprintf "Hello %s" "world"printf "%d times" 1

printf "%d times" 3 3

ERROR!

Page 19: Dependent Types with Idris

Type-safe Printfprintf "Hello %s" "world"printf "%d times" 1

Page 20: Dependent Types with Idris

Type-safe Printfprintf "Hello %s" : String -> Stringprintf "%d times" : Int -> String

Page 21: Dependent Types with Idris

Type-safe Printfprintf : (str : String) -> <Function type depending on str>

Page 22: Dependent Types with Idris

Type-safe Printfprintf : (str : String) -> PrintfType str

Page 23: Dependent Types with Idris

Type-safe Printfprintf : (str : String) -> PrintfType (toFormat (unpack str))

toFormat : List Char -> Format

PrintfType : Format -> Type

Page 24: Dependent Types with Idris

Type-safe Printfdata Format = Number Format | Str Format | Lit Char Format | End

> toFormat (unpack "a%s")Lit 'a' (Str End) : Format

> toFormat (unpack "%d")Number End

Page 25: Dependent Types with Idris

Type-safe PrintftoFormat : (xs : List Char) -> FormattoFormat [] = EndtoFormat ('%' :: 's' :: xs) = Str (toFormat xs)toFormat ('%' :: 'd' :: xs) = Number (toFormat xs)toFormat (x :: xs) = Lit x (toFormat xs)

Page 26: Dependent Types with Idris

Type-safe PrintfPrintfType : Format -> Type

PrintfType (Number fmt) = Int -> PrintfType fmtPrintfType (Str fmt) = String -> PrintfType fmtPrintfType (Lit x fmt) = PrintfType fmtPrintfType End = String

Page 27: Dependent Types with Idris

Type-safe Printfprintf : (str : String) -> PrintfType (toFormat (unpack str))printf str = printfFmt _ ""

where printfFmt : (fmt : Format) -> (acc : String) -> PrintfType fmt printfFmt (Number fmt) acc = \i => printfFmt fmt (acc ++ show i) printfFmt (Str fmt) acc = \s => printfFmt fmt (acc ++ s) printfFmt (Lit x fmt) acc = printfFmt fmt (acc ++ (singleton x)) printfFmt End acc = acc

Page 28: Dependent Types with Idris

Type-safe File Handles

DEMO

Page 29: Dependent Types with Idris

Even Numbersdata Even : Nat -> Type where EZ : Even Z ES : Even k -> Even (S (S k))

zeroIsEven : Even 0zeroIsEven = EZ

twoIsEven : Even 2twoIsEven = ES EZ

Page 30: Dependent Types with Idris

Proofs

Theorem: 4 is even

0 is even0 + 2 is even

(0 + 2) + 2 is even

fourIsEven : Even 4fourIsEven = ES (ES EZ)

Idris

Page 31: Dependent Types with Idris

Curry Howard Correspondence

Theorems correspond to Types

Proofs correspond to Programs

Page 32: Dependent Types with Idris

Equalitydata (=) : a -> b -> Type where Refl : x = x

twoIsTwo : 2 = 2twoIsTwo = Refl

3Plus2IsFive : 3 + 2 = 53Plus2IsFive = Refl

Page 33: Dependent Types with Idris

Falsity or the Empty Type

twoPlusTwoIsNotFive : 2 + 2 = 5 -> VoidtwoPlusTwoIsNotFive Refl impossible

data Void : Type where

Page 34: Dependent Types with Idris

Takeaway

Make illegal state unrepresentable

Page 35: Dependent Types with Idris

Thank You!Abdulsattar

[email protected]