# Tom Schrijvers K.U.Leuven, Belgium with Manuel Chakravarty, Martin Sulzmann and Simon Peyton Jones.

## Presentation on theme: "Tom Schrijvers K.U.Leuven, Belgium with Manuel Chakravarty, Martin Sulzmann and Simon Peyton Jones."— Presentation transcript:

Tom Schrijvers K.U.Leuven, Belgium with Manuel Chakravarty, Martin Sulzmann and Simon Peyton Jones

Type-level functions Functional programming at the type level! Examples Usefulness Interaction Type Checking Eliminating functional dependencies Examples Usefulness Interaction Type Checking Eliminating functional dependencies

Examples

Example: 1 + 1 = 2? -- Peano numerals data Z data Succ n -- Abbreviations type One = Succ Z type Two = Succ One -- Type-level addition type family Sum m n type instance Sum Z n = n type instance Sum (Succ a) b = Succ (Sum a b) -- Peano numerals data Z data Succ n -- Abbreviations type One = Succ Z type Two = Succ One -- Type-level addition type family Sum m n type instance Sum Z n = n type instance Sum (Succ a) b = Succ (Sum a b) type function declaration Sum :: * -> * -> * type function declaration Sum :: * -> * -> * 1 st type function instance 2 nd type function instance

Example: 1 + 1 = 2? -- Type-level addition type family Sum m n type instance Sum Z nat = nat type instance Sum (Succ a) b = Succ (Sum a b) -- Hypothesis hypthesis :: (Sum One One, Two) hypothesis = undefined -- Test test :: (a,a) -> Bool test _ = True -- Type-level addition type family Sum m n type instance Sum Z nat = nat type instance Sum (Succ a) b = Succ (Sum a b) -- Hypothesis hypthesis :: (Sum One One, Two) hypothesis = undefined -- Test test :: (a,a) -> Bool test _ = True

Example: 1 + 1 = 2? -- Hypothesis hypthesis :: (Sum One One, Two) hypothesis = undefined -- Test test :: (a,a) -> Bool test _ = True -- Proof proof :: Bool proof = test hypothesis -- Hypothesis hypthesis :: (Sum One One, Two) hypothesis = undefined -- Test test :: (a,a) -> Bool test _ = True -- Proof proof :: Bool proof = test hypothesis static check: 1+1 = 2

Example: Length-indexed Lists -- Length-indexed lists : vectors data Vec e l where VNil :: Vec e Z VCons :: e -> Vec e l -> Vec e (Succ l) -- Safe zip: matched lengths vzip :: Vec a l -> Vec b l -> Vec (a,b) l vzip VNil VNil = VNil vzip (VCons x xs) (VCons y ys) = VCons (x,y) (vzip xs ys) -- Length-indexed lists : vectors data Vec e l where VNil :: Vec e Z VCons :: e -> Vec e l -> Vec e (Succ l) -- Safe zip: matched lengths vzip :: Vec a l -> Vec b l -> Vec (a,b) l vzip VNil VNil = VNil vzip (VCons x xs) (VCons y ys) = VCons (x,y) (vzip xs ys)

Example: Length-indexed Lists -- Safe zip: matched lengths vzip :: Vec a l -> Vec b l -> Vec (a,b) l vzip VNil VNil = VNil vzip (VCons x xs) (VCons y ys) = VCons (x,y) (vzip xs ys) -- Safe zip: matched lengths vzip :: Vec a l -> Vec b l -> Vec (a,b) l vzip VNil VNil = VNil vzip (VCons x xs) (VCons y ys) = VCons (x,y) (vzip xs ys) > let l1 = (VCons 1 VNil) l2 = (VCons a (VCons b VNil)) in vzip l1 l2 12

Example: Length-indexed Lists -- Safe zip: matched lengths vzip :: Vec a l -> Vec b l -> Vec (a,b) l vzip VNil VNil = VNil vzip (VCons x xs) (VCons y ys) = VCons (x,y) (vzip xs ys) -- Safe zip: matched lengths vzip :: Vec a l -> Vec b l -> Vec (a,b) l vzip VNil VNil = VNil vzip (VCons x xs) (VCons y ys) = VCons (x,y) (vzip xs ys) > let l1 = (VCons 1 (VCons 2 VNil)) l2 = (VCons a (VCons b VNil)) in vzip l1 l2 VCons (1,a) (VCons (2,b) VNil) 2=2

Example: Length-indexed lists -- concatenation vconc :: Vec a m -> Vec a n -> Vec a ??? vconc VNil VNil = VNil Vconc (VCons x xs) ys = VCons x (vconc xs ys) -- concatenation vconc :: Vec a m -> Vec a n -> Vec a ??? vconc VNil VNil = VNil Vconc (VCons x xs) ys = VCons x (vconc xs ys)

Example: Length-indexed lists -- concatenation vconc :: Vec a m -> Vec a n -> Vec a (Sum m n) vconc VNil VNil = VNil Vconc (VCons x xs) ys = VCons x (vconc xs ys) -- concatenation vconc :: Vec a m -> Vec a n -> Vec a (Sum m n) vconc VNil VNil = VNil Vconc (VCons x xs) ys = VCons x (vconc xs ys) > let l1 = (VCons 1) l2 = (VCons a (VCons b VNil)) l3 = vconc l1 l1 in vzip l3 l2 VCons (1,a) (VCons (1,b) VNil) 1+1=2

Example: Collections (1/4) class Collection c where type Elem c add :: Elem c -> c -> c list :: c -> [Elem c] elem :: c -> Elem c Associated type function Elem :: * -> * Associated value function elem :: c -> Elem c

Example: Collections (2/4) instance Collection [e] where type Elem [e] = e instance Collection (Tree e) where type Elem (Tree e) = e instance Collection BitVector where type Elem BitVector = Bit type functions are open!

instance Collection [e] where type Elem [e] = e add :: e -> [e] -> [e] add x xs = x : xs list :: [e] -> [ e ] list xs = xs Example: Collections (3/4) instance Collection [e] where type Elem [e] = e add :: Elem [e] -> [e] -> [e] add x xs = x : xs list :: [e] -> [Elem [e]] list xs = xs

addAll :: c1 -> c2 -> c2 addAll xs ys = foldr add ys (list xs) Example: Collections (4/4) addAll :: Collection c1 => c1 -> c2 -> c2 addAll xs ys = foldr add ys (list xs) addAll :: Collection c1, Collection c2 => c1 -> c2 -> c2 addAll xs ys = foldr add ys (list xs) addAll :: Collection c1, Collection c2, Elem c1 ~ Elem c2=> c1 -> c2 -> c2 addAll xs ys = foldr add ys (list xs) > addAll [0,1,0,1,0] emptyBitVector context constraint, satisfied by caller context constraint, satisfied by caller Elem [Bit] ~ Elem BitVector

Summary of Examples functions over types open definitions stand-alone associated to a type class equational constraints in signature contexts usefulness limited on their own really great with GADTs type classes

Type Checking

Compiler Overview Haskell Constraints Type Checker Coercions System F C

Elem [Int] ~ Int ? γ Int :: Elem [Int] ~ Int ! Compiler Overview (elem [0]) (γ Int) == 0 elem [0] == 0γ : e.Elem [e] = e hypothesis axiom proof label witness cast

Basic Hindley-Milner [Int] ~ [Int] syntactic equality (unification) Type Functions Elem [Int] ~ Int syntactic equality modulo equational theory Type Checking = Syntactical?

Type Checking = Term Rewriting γ : e.Elem [e] = e Elem [Int] ~ Int Int γ Int Int Equational theory = given equations Toplevel equations: E t Context equations: E g Theorem proving Operational interpretation of theory = Term Rewriting System (Soundness!)

Completeness TRS must be Strongly Normalizing (SN): Confluent: every type has a canonical form Terminating TRS must be Strongly Normalizing (SN): Confluent: every type has a canonical form Terminating Practical & Modular Conditions: Confluence: no overlap of rule heads Terminating: Decreasing recursive calls No nested calls Practical & Modular Conditions: Confluence: no overlap of rule heads Terminating: Decreasing recursive calls No nested calls

Completeness Conditions Practical & Modular Conditions: Confluence: no overlap Elem [e] = e Elem [Int] = Bit Terminating: Decreasing recursive calls Elem [e] = Elem [[e]] No nested calls Elem [e] = Elem (F e) F e = [e] Practical & Modular Conditions: Confluence: no overlap Elem [e] = e Elem [Int] = Bit Terminating: Decreasing recursive calls Elem [e] = Elem [[e]] No nested calls Elem [e] = Elem (F e) F e = [e]

Term Rewriting Conditions EtEt EgEg E g We can do better: E t : satisfy conditions E g : free form(but no schema variabels) We can do better: E t : satisfy conditions E g : free form(but no schema variabels) EtEt Completion!

Type Checking Summary EtEt EgEg t1 ~ t2 E g t ~ t 1.Completion 2.Rewriting 3.Syntactic Equality Its all been implemented in GHC! Its all been implemented in GHC!

Eliminating Functional Dependencies

Functional Dependencies Using relations as functions Logic Programming! class Collection c e | c -> e where add :: e -> c -> c list :: c -> [e] elem :: c -> [e] instance Collection [e] e where...

FDs: Two Problems Haskell implementors are still debugging FD type checking Haskell programmers know Functional Programming FDs = Logic Programming

FDs: Solution Functional Dependencies Type Functions

FDs: Solution 2 Backward Compatibility??? Expressiveness lost??? automatic transformation

class FD c ~ e => Collection c e where type FD c add :: e -> c -> c list :: c -> [e] elem :: c -> e instance Collection [e] e where... class FD c ~ e => Collection c e where type FD c add :: e -> c -> c list :: c -> [e] elem :: c -> e instance Collection [e] e where type FD [e] = e class Collection c e | c -> e where add :: e -> c -> c list :: c -> [e] elem :: c -> [e] instance Collection [e] e where... class Collection c e | c -> e where type FD c add :: e -> c -> c list :: c -> [e] elem :: c -> e instance Collection [e] e where... FDs: Simple Transformation Minimal Impact: class and instance declarations only

class FD c ~ e => Collection c where type FD c add :: e -> c -> c list :: c -> [e] elem :: c -> e instance Collection [e] e where type FD [e] = e class Collection c where type FD c add :: FD c -> c -> c list :: c -> [FD c] elem :: c -> FD c instance Collection [e] where type FD [e] = e FDs: Advanced Transformation Drop dependent parameters class FD c ~ e => Collection c e where type FD c add :: e -> c -> c list :: c -> [e] elem :: c -> e instance Collection [e] e where type FD [e] = e

class FD c ~ e => Collection c e where type FD c addAll :: Collection c1 e, Collection c2 e =>... FDs: Advanced Transformation Bigger Impact: signature contexts too class Collection c where type FD c addAll :: Collection c1 e, Collection c2 e =>... class Collection c where type FD c addAll :: Collection c1, Collection c2, Elem c1 ~ Elem c2 =>...

Conclusion

Type checking with type functions = Term Rewriting sound, complete and terminating completion algorithm Seemless integration in Haskells rich type system Type classes GADTs Understanding functional dependencies better Type checking with type functions = Term Rewriting sound, complete and terminating completion algorithm Seemless integration in Haskells rich type system Type classes GADTs Understanding functional dependencies better

Future Work Improvements and variations Weaker termination conditions Closed type functions Rational tree types Efficiency Applications: Port libraries Revisit type hacks Write some papers! Improvements and variations Weaker termination conditions Closed type functions Rational tree types Efficiency Applications: Port libraries Revisit type hacks Write some papers!

Extra Slide

Rational tree types -- Non-recursive list data List e t = Nil | Cons e t -- Fixedpoint operator type family Fix (k :: *->*) type instance Fix k = k (Fix k) -- Tie the knot type List e = Fix (List e) = List e (List e (List e …))

Download ppt "Tom Schrijvers K.U.Leuven, Belgium with Manuel Chakravarty, Martin Sulzmann and Simon Peyton Jones."

Similar presentations