Download - types, types, types

Transcript
Page 1: types, types, types

types, types, types

Page 2: types, types, types

types, types, typesIn a weird parallel world where programming is based on type theory, every term has a type, if you declare it or not, every function has a type, and polymorphic functions can't know the type of their argument or see what's inside.

Even if you don't use languages from that world, they can still be an inspiration.

Page 3: types, types, types

goals

Page 4: types, types, types

dissatisfied

excited

common language

Page 5: types, types, types

outlinewarm-up. just ask the type inferencer

main A. type checking is lie detectionmain B. what is type theory anyway?

examples.

bonus. kinds

Page 6: types, types, types

just ask thetype inferencer

Page 7: types, types, types

just ask the type inferencerghci> :type 3 > 0

Hey type inferencer, I was just wondering:

4 What's the type of 3 > 0?

Page 8: types, types, types

just ask the type inferencerghci> :type 3 > 0

3 > 0 :: Bool

The term 3 > 0 has the type Bool.

Page 9: types, types, types

just ask the type inferencerghci> :type not

Page 10: types, types, types

just ask the type inferencerghci> :type not

not :: Bool -> Bool

"not" is a function that takes a Bool to a Bool.

Page 11: types, types, types

just ask the type inferencerghci> let f (x, y) = Trueghci> :type f

Page 12: types, types, types

just ask the type inferencerghci> let f (x, y) = Trueghci> :type f

f :: (t, t1) -> Bool

f is a function that takes a pair ofany two types to a Bool.

someVar = f (True, "abc") -- True

Page 13: types, types, types

just ask the type inferencerghci> let f x y = x == yghci> :type f

Page 14: types, types, types

just ask the type inferencerghci> let f x y = x == yghci> :type f

f :: Eq a => a -> a -> Bool

f is a function that takes two of thesame type "a" to a Bool.

The type "a" must support equality.

Page 15: types, types, types

just ask the type inferencerghci> :info Eq

class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool

("a" is a placeholder for a concrete type here.)

Page 16: types, types, types

just ask the type inferencerghci> let f x = x * 2ghci> :type f

Page 17: types, types, types

just ask the type inferencerghci> let f x = x * 2ghci> :type f

f :: Num a => a -> a

f is a function that takes a value of any type "a" to a value of the same type "a".

There must be an instance of Num for the type "a".

Page 18: types, types, types

just ask the type inferencerghci> :info Num

class Num a where (+) :: a -> a -> a (*) :: a -> a -> a (-) :: a -> a -> a negate :: a -> a abs :: a -> a ...

Page 19: types, types, types

just ask the type inferencerghci> let f x = x * 2ghci> f True

<interactive>:24:1: No instance for (Num Bool) arising from a use of `f' Possible fix: add an instance declaration for (Num Bool) In the expression: f True In an equation for `it': it = f True

Page 20: types, types, types

ok

Page 21: types, types, types

summary4 if you don't know the type, ask the type inferencer

4 functions have types

4 operations constrain types

Page 22: types, types, types

main A

Page 23: types, types, types

type checkingis lie detection

Page 24: types, types, types

type checking is lie detectionintIdentity :: Int -> IntintIdentity x = x

Page 25: types, types, types

type checking is lie detectionintIdentity :: Int -> IntintIdentity x = 42

But that's not an identity function! :(

Page 26: types, types, types

how can we prevent ourselves from lying?

Page 27: types, types, types

the function that…

Page 28: types, types, types

type checking is lie detection-- intIdentity :: Int -> Intidentity :: a -> aidentity x = ???

Page 29: types, types, types

type checking is lie detection-- intIdentity :: Int -> Intidentity :: a -> aidentity x = 42

Page 30: types, types, types

type checking is lie detection-- intIdentity :: Int -> Intidentity :: a -> aidentity x = 42

That's a lie!The function must accept an argument of any type.

Page 31: types, types, types

type checking is lie detection-- intIdentity :: Int -> Intidentity :: a -> aidentity x = 42

That's a lie!The function must accept an argument of any type.And it must return an argument of the same type.

Page 32: types, types, types

type checking is lie detection-- intIdentity :: Int -> Intidentity :: a -> aidentity x = x

There is only one valid implementation*!

*that terminates and returns a value

Page 33: types, types, types

parametricity

Page 34: types, types, types
Page 35: types, types, types

c++ templates and parametricitytemplate <typename t>t identity(t a) { return ???;}

Page 36: types, types, types

c++ templates and parametricitytemplate <typename t>t identity(t a) { return 42;}

Page 37: types, types, types

end of intermission

Page 38: types, types, types

parametricityf :: [t] -> [t]

What can this function not do?

Page 39: types, types, types

parametricityf :: [t] -> [t]

What can this function not do?

4 insert items

4 change values

Page 40: types, types, types

parametricityf :: [t] -> [t]

So what can it do at all?

Page 41: types, types, types

parametricityf :: [t] -> [t]

So what can it do at all?

4 rearrange list items

4 drop list items

Page 42: types, types, types

parametricityHere is a valid implementation:

tail :: [t] -> [t]tail (x:xs) = xs -- non-emptytail _ = [] -- empty

-- example usage:-- tail [1,2,3] -- [2,3]-- tail "abc" -- "bc"-- tail [] -- []-- tail "" -- ""

Page 43: types, types, types

parametricity / lie detectionf :: [t] -> t

Page 44: types, types, types

parametricity / lie detectionhead :: [t] -> thead (x:_) = x

Page 45: types, types, types

parametricity / lie detectionhead :: [t] -> thead (x:_) = x

Warning: Pattern match(es) are non-exhaustive In an equation for `head': Patterns not matched: []

Page 46: types, types, types

parametricity / lie detectionhead :: [t] -> thead (x:_) = xhead [] = ???

4 the type [t] -> t is not inhabited

4 any function that claims to have that type is a lie

Page 47: types, types, types

summary4 the less a function knows, the less it can do

4 if you can use a more abstract type, do it

4 not every type is inhabited

Page 48: types, types, types

main B

Page 49: types, types, types

what istype theory

anyway?

Page 50: types, types, types

"type theory is the grand, unified theory of computation"— robert harper

Page 51: types, types, types

type theory is a formal language that describeshow terms and typesrelate to each other

Page 52: types, types, types

example: pairs4 how to combine two types into a pair type

4 how to construct values of that type

4 how to deconstruct pair values and types

4 how to simplify terms involving pairs

Page 53: types, types, types

type theory: formation rulesA is a type <—— "assuming that…"B is a type——————————————— (∧F)A ∧ B is a type <—— "…this is a valid thing to write"

Page 54: types, types, types

type theory: introduction rulesA is a typeB is a type——————————————— (∧F)A ∧ B is a type

x:A y:B——————————— (∧-Introduction)(x,y) : A∧B

Page 55: types, types, types

type theory: elimination rulesA is a typeB is a type——————————————— (∧F)A ∧ B is a type

x:A y:B z : A∧B——————————— (∧I) ——————————— (∧E1)(x,y) : A∧B first z : A

Page 56: types, types, types

type theory: elimination rulesA is a typeB is a type——————————————— (∧F)A ∧ B is a type

x:A y:B z : A∧B z : A∧B——————————— (∧I) ——————————— (∧E1) ———————————— (∧E2)(x,y) : A∧B first z : A second z : B

Page 57: types, types, types

type theory: computation rulesfirst(x,y) —> x

second(x,y) —> y

(The left side reduces to the right side.)

Page 58: types, types, types

4 formation rulesspecify syntax for types

4 introduction rulesspecify syntax for types and terms

4 elimination rulesare inverses of introduction rules (sort of)

4 computation rulesdescribe how terms can be simplified by evaluating them

Page 59: types, types, types

next example: functions

Page 60: types, types, types

type theory: implicationpropositional logic-------------------

A => B assuming that A implies BA and assuming there is a proof of A—————— B there is a proof of B

Page 61: types, types, types

type theory: implicationpropositional logic type theory------------------- -----------

A => B f : (A => B)A x : A—————— ———————————— (=> Elimination) B (f x) : B

Page 62: types, types, types

type theory: implicationHow do we construct a function?

Page 63: types, types, types

type theory: implicationHow do we construct a function?

x:A . . given an object of type A, . an object of type B can be deduced . ——— y:B

Page 64: types, types, types

type theory: implicationHow do we construct a function?

[x:A] [discharged assumption] . . given an object of type A, . an object of type B can be deduced . y:B———————————————— (=> Introduction) ??? : A => B

Page 65: types, types, types

type theory: implicationHow do we construct a function?

[x:A] [discharged assumption] . . given an object of type A, . an object of type B can be deduced . y:B———————————————— (=>I)(λx. y) : A => B any function that takes an A and returns a B is a proof of A => B

Page 66: types, types, types

type theory: implicationintroduction: elimination:

[x:A] f: A => B x:A . ——————————————— . (f x) : B . y:B———————————————— computation:(λx. y) : A => B beta reduction

Page 67: types, types, types

a program is well-typedif it can be derived

using the rules

Page 68: types, types, types

types as propositions

programs as proofs

Page 69: types, types, types

"Curry–Howard correspondence"

Page 70: types, types, types

what does that mean for some actual programs?

Page 71: types, types, types

programs as proofsx :: Bool

Page 72: types, types, types
Page 73: types, types, types

programs as proofsx :: Boolx = False

Page 74: types, types, types

programs as proofsx :: Boolx = False

(empty) (empty)——————————— ————————————True : bool False : bool

False is exactly one of the ways of how you construct a bool.

Page 75: types, types, types

not bad

Page 76: types, types, types

programs as proofsdata Color = Red | Green | Blue

c :: Color

Page 77: types, types, types

programs as proofsdata Color = Red | Green | Blue

c :: Colorc = Blue

Blue is exactly one of the ways of how you construct a Color.

Page 78: types, types, types

programs as proofsf :: (a -> b) -> a -> b

Page 79: types, types, types
Page 80: types, types, types

programs as proofsf :: (a -> b) -> a -> bf f1 x = ???

Page 81: types, types, types

programs as proofsf :: (a -> b) -> a -> bf f1 x = f1 x

Page 82: types, types, types

programs as proofsf :: (a -> b) -> a -> bf f1 x = f1 x

Why does a function of that type exist?

Page 83: types, types, types

programs as proofsf :: (a -> b) -> a -> bf f1 x = f1 x

Why does a function of that type exist?

A => B A———————————— B

Page 84: types, types, types

programs as proofsf :: (a -> b) -> a -> bf f1 x = f1 x

Why does a function of that type exist?

A => B [A]———————————— A => B

Page 85: types, types, types

programs as proofsf :: (a -> b) -> (a -> b)f f1 x = f1 x

Why does a function of that type exist?

[A => B] [A]———————————————————— (sort of a silly proof)(A => B) => (A => B)

Page 86: types, types, types

if it's provable, you can write a program

a well-typed program constitutes a proof

Page 87: types, types, types

programs as proofsf :: (b -> c) -> (a -> b) -> a -> cf f1 f2 x = ???

Page 88: types, types, types

programs as proofsf :: (b -> c) -> (a -> b) -> a -> cf f1 f2 x = ???

compare:

A => B B => C——————————————— transitivity A => C

Page 89: types, types, types

programs as proofsf :: (b -> c) -> (a -> b) -> a -> cf f1 f2 x = f1 (f2 x)

compare:

A => B B => C——————————————— transitivity A => C

Page 90: types, types, types

programs as proofsf :: (a -> b -> c) -> b -> a -> c

Page 91: types, types, types

programs as proofsflip :: (a -> b -> c) -> b -> a -> cflip f y x = f x y

Page 92: types, types, types

programs as proofsflip :: (a -> b -> c) -> b -> a -> cflip f y x = f x y

So what is flip a proof of?

Page 93: types, types, types

programs as proofsflip :: (a -> b -> c) -> b -> a -> cflip f y x = f x y

So what is flip a proof of?

4 commutativity of implication

(A => (B => C)) <=> (B => (A => C))

Page 94: types, types, types
Page 95: types, types, types

but not every typehas a proof

Page 96: types, types, types

programs as proofsf :: a -> bf x = ???

Page 97: types, types, types

programs as proofsf :: a -> bf x = ???

If there is such a function, A => B must be provable.

?——————A => B

Page 98: types, types, types

programs as proofsf :: a -> bf x = ???

If there is such a function, A => B must be provable.

Nope.——————A => B

Page 99: types, types, types

programs as proofsf :: a -> bf x = ???

-- hypothetical usage examples:foo :: Int bar :: Boolfoo = f "hello" bar = f "hello"

Page 100: types, types, types

programs as proofsf :: a -> bf x = ???

-- hypothetical usage examples:foo :: Int bar :: Boolfoo = f "hello" bar = f "hello"

You can't construct a value of an unknown type.

Page 101: types, types, types
Page 102: types, types, types

c++ templates and proofstemplate <typename t, typename t2>t2 f(t a, t2 b) { return ???;}

Page 103: types, types, types

c++ templates and proofstemplate <typename t, typename t2>t2 f(t a, t2 b) { return "whatever";}

okay, so…

`typename t` does not mean `∀t`

Page 104: types, types, types

end of intermission

Page 105: types, types, types

summary4 type theory is a formal language that describes how

terms and types relate to each other

4 a program is a proof of its type

4 not every type has a proof (or is inhabited)

Page 106: types, types, types

end of theory

Page 107: types, types, types

so like, how would iwrite a head function

if i needed to?

Page 108: types, types, types

3 options

Page 109: types, types, types

option 1: more explicit input typetype NonEmptyList a = (a, [a])

Page 110: types, types, types

option 1: more explicit input typetype NonEmptyList a = (a, [a])

head :: NonEmptyList a -> ahead (x, _) = x

Page 111: types, types, types

option 2: more explicit output type-- head :: [a] -> ??head (x:_) = ThereIsTotallyAn x

Page 112: types, types, types

option 2: more explicit output type-- head :: [a] -> ??head (x:_) = ThereIsTotallyAn xhead [] = NopeNothingNada

Page 113: types, types, types

option 2: more explicit output typehead :: [a] -> MaybeAn ahead (x:_) = ThereIsTotallyAn xhead [] = NopeNothingNada

Page 114: types, types, types

option 2: more explicit output typehead :: [a] -> MaybeAn ahead (x:_) = ThereIsTotallyAn xhead [] = NopeNothingNada

data MaybeAn a = ThereIsTotallyAn a | NopeNothingNada

MaybeAn a may contain an a, but it is not an a itself.

Page 115: types, types, types

option 2: more explicit output typehead :: [a] -> Maybe ahead (x:_) = Just xhead [] = Nothing

data Maybe a = Just a | Nothing

Maybe a may contain an a, but it is not an a itself.

Page 116: types, types, types

option 3: length-aware list typedata TaggedList length a -- -- add here: constructors for -- empty and non-empty lists --

data Zero -- 0data Succ n -- 1, 2, 3, 4, 5, 6, …

head :: TaggedList (Succ n) a -> ahead (x : _) = x

Page 117: types, types, types

option 3: length-aware list typedata TaggedList length a where Empty :: TaggedList Zero a (:.) :: a -- an item -> TaggedList length a -- a list -> TaggedList (Succ length) a -- a longer list

data Zero -- 0data Succ n -- 1, 2, 3, 4, 5, 6, …

head :: TaggedList (Succ n) a -> ahead (x :. _) = x

Page 118: types, types, types

wow

Page 119: types, types, types

let's do somestatic duck-typing!

Page 120: types, types, types

duck —> type# THIS IS PYTHON

def foo(x): return x * 2

print foo(3) # 6print foo("hi") # "hihi"

Page 121: types, types, types

duck —> typefoo x = x * 2

main = do print (foo 3) -- 6

  ghci> :type foofoo :: Num a => a -> a

Page 122: types, types, types

duck —> typefoo x = x * 2

main = do print (foo 3) print (foo "hi")

No instance for (Num [Char]) arising from a use of `foo'Possible fix: add an instance declaration for (Num [Char])In the first argument of `print', namely `(foo "hi")'In a stmt of a 'do' block: print (foo "hi")

Page 123: types, types, types

duck —> typeclass Mul a where (*) :: a -> Int -> a

(a can be any concrete type)

Page 124: types, types, types

duck —> typeclass Mul a where (*) :: a -> Int -> a

instance Mul Int where x * y = x Builtin.* y

instance Mul String where x * 1 = x x * n | n <= 0 = "" | n > 0 = x ++ x * (n - 1)

Page 125: types, types, types

duck —> typemain = do print (foo 3::Int) -- 6 print (foo "hi") -- "hihi"

Boom. Done. Works.

Page 126: types, types, types

bonus:

kinds

Page 127: types, types, types

kindsThe comma in (Bool, Int) is a type-forming operator!

ghci> :kind (,)(,) :: * -> * -> *

Page 128: types, types, types

kindsThe comma in (Bool, Int) is a type-forming operator!

ghci> :kind (,)(,) :: * -> * -> *

ghci> :kind (,) Bool(,) Bool :: * -> *

Page 129: types, types, types

kindsThe comma in (Bool, Int) is a type-forming operator!

ghci> :kind (,)(,) :: * -> * -> *

ghci> :kind (,) Bool(,) Bool :: * -> *

ghci> :kind (,) Bool Int(,) Bool Int :: *

Page 130: types, types, types

kindsghci> :kind [Int][] :: *

ghci> :kind [][] :: * -> *

Page 131: types, types, types

alright

Page 132: types, types, types

Reading recommendation4 TTFP — Type Theory and Functional Programming

Page 133: types, types, types

fin

Page 134: types, types, types

questions

Page 135: types, types, types

questions

Page 136: types, types, types

appendix

Page 137: types, types, types

nested listsvar nestedList = [ 1 , 2 , [ 3 , [ 4, 5 ] ] ];

Page 138: types, types, types

nested listsdata NestedList a = Atom a | Nest [NestedList a]

nestedList :: NestedList IntnestedList = Nest [ Atom 1 , Atom 2 , Nest [ Atom 3 , Nest [ Atom 4 , Atom 5 ] ] ]