Type-level functions for Haskell

Download Type-level functions  for Haskell

Post on 24-Feb-2016

33 views

Category:

Documents

0 download

Embed Size (px)

DESCRIPTION

Type-level functions for Haskell. 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 - PowerPoint PPT Presentation

TRANSCRIPT

<p>Type-level functions for Haskell</p> <p>Type-level functions for HaskellTom SchrijversK.U.Leuven, Belgiumwith Manuel Chakravarty, Martin Sulzmann and Simon Peyton JonesType-level functionsFunctional programming at the type level!ExamplesUsefulnessInteractionType CheckingEliminating functional dependencies</p> <p>ExamplesExample: 1 + 1 = 2?-- Peano numeralsdata Zdata Succ n</p> <p>-- Abbreviationstype One = Succ Ztype Two = Succ One</p> <p>-- Type-level additiontype family Sum m ntype instance Sum Z n = ntype instance Sum (Succ a) b = Succ (Sum a b)</p> <p>type function declarationSum :: * -&gt; * -&gt; *1st type function instance2nd type function instanceExample: 1 + 1 = 2?-- Type-level additiontype family Sum m ntype instance Sum Z nat = nattype instance Sum (Succ a) b = Succ (Sum a b)</p> <p>-- Hypothesishypthesis :: (Sum One One, Two)hypothesis = undefined</p> <p>-- Testtest :: (a,a) -&gt; Booltest _ = True</p> <p>Example: 1 + 1 = 2?-- Hypothesishypthesis :: (Sum One One, Two)hypothesis = undefined</p> <p>-- Testtest :: (a,a) -&gt; Booltest _ = True</p> <p>-- Proofproof :: Boolproof = test hypothesis</p> <p>static check: 1+1 = 2Example: Length-indexed Lists-- Length-indexed lists : vectorsdata Vec e l where VNil :: Vec e Z VCons :: e -&gt; Vec e l -&gt; Vec e (Succ l)</p> <p>-- Safe zip: matched lengthsvzip :: Vec a l -&gt; Vec b l -&gt; Vec (a,b) lvzip VNil VNil = VNilvzip (VCons x xs) (VCons y ys) = VCons (x,y) (vzip xs ys)Example: Length-indexed Lists-- Safe zip: matched lengthsvzip :: Vec a l -&gt; Vec b l -&gt; Vec (a,b) lvzip VNil VNil = VNilvzip (VCons x xs) (VCons y ys) = VCons (x,y) (vzip xs ys)&gt; let l1 = (VCons 1 VNil) l2 = (VCons a (VCons b VNil)) in vzip l1 l212Example: Length-indexed Lists-- Safe zip: matched lengthsvzip :: Vec a l -&gt; Vec b l -&gt; Vec (a,b) lvzip VNil VNil = VNilvzip (VCons x xs) (VCons y ys) = VCons (x,y) (vzip xs ys)&gt; let l1 = (VCons 1 (VCons 2 VNil)) l2 = (VCons a (VCons b VNil)) in vzip l1 l2VCons (1,a) (VCons (2,b) VNil)2=2Example: Length-indexed lists-- concatenationvconc :: Vec a m -&gt; Vec a n -&gt; Vec a ???vconc VNil VNil = VNilVconc (VCons x xs) ys = VCons x (vconc xs ys)Example: Length-indexed lists-- concatenationvconc :: Vec a m -&gt; Vec a n -&gt; Vec a (Sum m n)vconc VNil VNil = VNilVconc (VCons x xs) ys = VCons x (vconc xs ys)&gt; let l1 = (VCons 1) l2 = (VCons a (VCons b VNil)) l3 = vconc l1 l1 in vzip l3 l2VCons (1,a) (VCons (1,b) VNil)1+1=2Example: Collections (1/4)class Collection c where</p> <p> type Elem c</p> <p> add :: Elem c -&gt; c -&gt; c list :: c -&gt; [Elem c] elem :: c -&gt; Elem c</p> <p>Associated type function Elem :: * -&gt; *Associated value functionelem :: c -&gt; Elem cExample: Collections (2/4)instance Collection [e] where type Elem [e] = einstance Collection (Tree e) where type Elem (Tree e) = einstance Collection BitVector where type Elem BitVector = Bittype functions are open!instance Collection [e] where type Elem [e] = e add :: e -&gt; [e] -&gt; [e] add x xs = x : xs</p> <p> list :: [e] -&gt; [ e ] list xs = xsExample: Collections (3/4)instance Collection [e] where type Elem [e] = e add :: Elem [e] -&gt; [e] -&gt; [e] add x xs = x : xs</p> <p> list :: [e] -&gt; [Elem [e]] list xs = xsaddAll :: c1 -&gt; c2 -&gt; c2addAll xs ys = foldr add ys (list xs)Example: Collections (4/4)addAll :: Collection c1 =&gt; c1 -&gt; c2 -&gt; c2addAll xs ys = foldr add ys (list xs)addAll :: Collection c1, Collection c2 =&gt; c1 -&gt; c2 -&gt; c2addAll xs ys = foldr add ys (list xs)addAll :: Collection c1, Collection c2, Elem c1 ~ Elem c2=&gt; c1 -&gt; c2 -&gt; c2addAll xs ys = foldr add ys (list xs)&gt; addAll [0,1,0,1,0] emptyBitVector</p> <p>context constraint,satisfied by callerElem [Bit] ~ Elem BitVectorSummary of Examplesfunctions over typesopen definitions stand-alone associated to a type classequational constraints in signature contextsusefulnesslimited on their ownreally great withGADTstype classes</p> <p>Type CheckingCompiler OverviewElem [Int] ~ Int ? Int :: Elem [Int] ~ Int !Compiler Overview(elem [0]) ( Int) == 0elem [0] == 0 : e.Elem [e] = ehypothesisaxiomprooflabelwitnesscastABasic Hindley-Milner[Int] ~ [Int]</p> <p>syntactic equality (unification)</p> <p>Type Functions Elem [Int] ~ Int</p> <p>syntactic equality modulo equational theoryType Checking = Syntactical?Type Checking = Term Rewriting : e.Elem [e] = eAElem [Int] ~ IntIntInt IntIntEquational theory = given equationsToplevel equations: EtContext equations: E gTheorem proving Operational interpretation of theory= Term Rewriting System (Soundness!)</p> <p>CompletenessTRS must be Strongly Normalizing (SN):Confluent: every type has a canonical formTerminating</p> <p>Practical &amp; Modular Conditions:Confluence: no overlap of rule headsTerminating:Decreasing recursive callsNo nested calls</p> <p>Completeness ConditionsPractical &amp; Modular Conditions:Confluence: no overlapElem [e] = eElem [Int] = BitTerminating:Decreasing recursive callsElem [e] = Elem [[e]]No nested callsElem [e] = Elem (F e)F e = [e] Term Rewriting ConditionsEtEgEgWe can do better:Et: satisfy conditionsEg: free form(but no schema variabels)</p> <p>EtCompletion!Type Checking SummaryEtEgt1 ~ t2Egt ~ t1.Completion2.Rewriting3.Syntactic EqualityIts all been implemented in GHC!Eliminating Functional DependenciesFunctional DependenciesUsing relations as functionsLogic Programming!class Collection c e | c -&gt; e where add :: e -&gt; c -&gt; c list :: c -&gt; [e] elem :: c -&gt; [e]</p> <p>instance Collection [e] e where ...FDs: Two ProblemsFDs: Solution</p> <p>FDs: Solution 2Backward Compatibility???Expressiveness lost???FDsTFsautomatic transformationclass FD c ~ e =&gt; Collection c e where type FD c add :: e -&gt; c -&gt; c list :: c -&gt; [e] elem :: c -&gt; e</p> <p>instance Collection [e] e where ...class FD c ~ e =&gt; Collection c e where type FD c add :: e -&gt; c -&gt; c list :: c -&gt; [e] elem :: c -&gt; e</p> <p>instance Collection [e] e where type FD [e] = e class Collection c e | c -&gt; e where add :: e -&gt; c -&gt; c list :: c -&gt; [e] elem :: c -&gt; [e]</p> <p>instance Collection [e] e where ...class Collection c e | c -&gt; e where type FD c add :: e -&gt; c -&gt; c list :: c -&gt; [e] elem :: c -&gt; e</p> <p>instance Collection [e] e where ...FDs: Simple TransformationMinimal Impact: class and instance declarations onlyclass FD c ~ e =&gt; Collection c where type FD c add :: e -&gt; c -&gt; c list :: c -&gt; [e] elem :: c -&gt; e</p> <p>instance Collection [e] e where type FD [e] = e class Collection c where type FD c add :: FD c -&gt; c -&gt; c list :: c -&gt; [FD c] elem :: c -&gt; FD c</p> <p>instance Collection [e] where type FD [e] = e FDs: Advanced TransformationDrop dependent parametersclass FD c ~ e =&gt; Collection c e where type FD c add :: e -&gt; c -&gt; c list :: c -&gt; [e] elem :: c -&gt; e</p> <p>instance Collection [e] e where type FD [e] = e class FD c ~ e =&gt; Collection c e where type FD c addAll :: Collection c1 e, Collection c2 e =&gt; ...FDs: Advanced TransformationBigger Impact: signature contexts tooclass Collection c where type FD c addAll :: Collection c1 e, Collection c2 e =&gt; ...class Collection c where type FD c addAll :: Collection c1, Collection c2, Elem c1 ~ Elem c2 =&gt; ...ConclusionConclusionType checking with type functions = Term Rewriting sound, complete and terminatingcompletion algorithm Seemless integration in Haskells rich type systemType classesGADTsUnderstanding functional dependencies betterFuture WorkImprovements and variationsWeaker termination conditionsClosed type functionsRational tree typesEfficiencyApplications: Port librariesRevisit type hacksWrite some papers!Extra SlideRational tree types-- Non-recursive listdata List e t = Nil | Cons e t</p> <p>-- Fixedpoint operatortype family Fix (k :: *-&gt;*)type instance Fix k = k (Fix k)</p> <p>-- Tie the knottype List e = Fix (List e) = List e (List e (List e ))</p>