tom schrijvers k.u.leuven, belgium with manuel chakravarty, martin sulzmann and simon peyton jones

38
Type-level functions for Haskell Tom Schrijvers K.U.Leuven, Belgium with Manuel Chakravarty, Martin Sulzmann and Simon Peyton Jones

Upload: keyon-yell

Post on 30-Mar-2015

216 views

Category:

Documents


3 download

TRANSCRIPT

  • Slide 1

Tom Schrijvers K.U.Leuven, Belgium with Manuel Chakravarty, Martin Sulzmann and Simon Peyton Jones Slide 2 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 Slide 3 Examples Slide 4 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 Slide 5 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 Slide 6 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 Slide 7 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) Slide 8 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 Slide 9 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 Slide 10 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) Slide 11 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 Slide 12 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 Slide 13 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! Slide 14 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 Slide 15 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 Slide 16 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 Slide 17 Type Checking Slide 18 Compiler Overview Haskell Constraints Type Checker Coercions System F C Slide 19 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 Slide 20 Basic Hindley-Milner [Int] ~ [Int] syntactic equality (unification) Type Functions Elem [Int] ~ Int syntactic equality modulo equational theory Type Checking = Syntactical? Slide 21 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!) Slide 22 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 Slide 23 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] Slide 24 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! Slide 25 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! Slide 26 Eliminating Functional Dependencies Slide 27 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... Slide 28 FDs: Two Problems Haskell implementors are still debugging FD type checking Haskell programmers know Functional Programming FDs = Logic Programming Slide 29 FDs: Solution Functional Dependencies Type Functions Slide 30 FDs: Solution 2 Backward Compatibility??? Expressiveness lost??? automatic transformation Slide 31 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 Slide 32 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 Slide 33 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 =>... Slide 34 Conclusion Slide 35 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 Slide 36 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! Slide 37 Extra Slide Slide 38 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 ))