Top Banner
Dependent Types with Abdulsattar
35

Dependent Types with Idris

Jan 26, 2017

Download

Software

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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]