Download Type-level functions for Haskell

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
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
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 …))
Related documents