Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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 Example: 1 + 1 = 2? -- Peano numerals data Z data Succ n -- Abbreviations type = Succ Zdeclaration typeOne function type Two = Succ One st type Sum 1:: * function -> * ->instance * -- Type-level2nd addition type function instance type family Sum m n type instance Sum Z n = n type instance Sum (Succ a) b = Succ (Sum a b) 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 Example: 1 + 1 = 2? -- Hypothesis hypthesis :: (Sum One One, Two) hypothesis = undefined -- Test test :: (a,a) -> Bool test _ = True -- Proof static check: 1+1 = 2 proof :: Bool proof = test hypothesis 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) 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) 1≠2 > let l1 = (VCons 1 VNil) l2 = (VCons ‘a’ (VCons ‘b’ VNil)) in vzip l1 l2 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) 2=2 > let l1’ = (VCons 1 (VCons 2 VNil)) l2 = (VCons ‘a’ (VCons ‘b’ VNil)) in vzip l1’ l2 VCons (1,’a’) (VCons (2,’b’) VNil) 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) 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) 1+1=2 > 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) 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 value function elem :: c -> Elem c Associated type function Elem :: * -> * Example: Collections (2/4) instance Collection [e] where type Elem [e] = e type functions are open! Collection (Tree e) where instance type Elem (Tree e) = e instance Collection BitVector where type Elem BitVector = Bit Example: Collections (3/4) instance Collection [e] where type Elem [e] = e add :: Elem e [e] -> [e] -> [e] add x xs = x : xs list :: [e] -> [Elem [ e [e]] ] list xs = xs Example: Collections (4/4) context constraint, satisfied by caller addAll :: Collection c1, c1 Collection c2 c2, => c1 Elem ->c1 c2~-> Elem c2 c2=> c1 -> c2 -> c2 addAll xs ys = foldr add ys (list xs) Elem [Bit] ~ Elem BitVector > addAll [0,1,0,1,0] emptyBitVector <010101> 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 FC Compiler Overview elem [0] == 0 label γ : e.Elem [e] = e axiom Elem [Int] ~ Int ? hypothesis proof witness γ Int :: Elem [Int] ~ Int ! cast (elem [0]) ► (γ Int) == 0 Type Checking = Syntactical? Basic Hindley-Milner [Int] ~ [Int] syntactic equality (unification) Type Functions Elem [Int] ~ Int syntactic equality modulo equational theory Type Checking = Term Rewriting Equational theory = given equations Toplevel equations: Et Context equations: E g γ : e.Elem [e] = e Theorem proving Operational interpretation of theory = Term Rewriting System (Soundness!) Elem [Int] ~ Int γ Int Int Int ≡ Int Completeness 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 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] Term Rewriting Conditions We can do better: Et: satisfy conditions Eg: free form √ (but no schema variabels) Et Et √ Eg’ Eg Completion! Type Checking Summary Et Eg It’s all been Eg’ implemented 3.Syntactic 1.Completion in GHC! Equality t ~ t t1 ~ t2 2.Rewriting 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 programmers know FDs Functional Programming = Logic Programming Haskell implementors are still debugging FD type checking FDs: Solution Functional Dependencies Type Functions FDs: Solution 2 Backward Compatibility??? Expressiveness lost??? automatic transformation FDs: Simple Transformation Minimal Impact: class and instance declarations only class Collection FD c ~ e =>cCollection e | c -> ecwhere e where add :: type FD c e -> c -> c list :: c add e -> c [e] -> c elem :: c -> [e] list elem :: c -> e instance Collection [e] e where type ... FD [e] = e FDs: Advanced Transformation Drop dependent parameters class FD Collection c ~ e =>cCollection where c where e where type FD c add :: e FD-> c c ->-> c c -> c list :: c -> [e] [FD c] elem :: c -> e FD c instance Collection [e] e where where type FD [e] = e FDs: Advanced Transformation Bigger Impact: signature contexts too class Collection c where class Collection FD c ~ e =>cCollection where c e where type FD c type FD c addAll :: Collection c1, Collection c2, addAll :: Collection c1 e, Collection c2 e Elem c1 ~ Elem c2 => ... => ... Conclusion Conclusion Type checking with type functions = Term Rewriting sound, complete and terminating completion algorithm Seemless integration in Haskell’s 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! 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 …))