300 likes | 514 Views
Modular Type Classes. Derek Dreyer Robert Harper Manuel M.T. Chakravarty POPL 2007 Nice, France. Specifications. Haskell:. Specifications. Haskell:. ML:. Implementations. Haskell:. Implementations. Haskell:. ML:. Generic Implementations. Haskell:. Generic Implementations.
E N D
Modular Type Classes Derek Dreyer Robert Harper Manuel M.T. Chakravarty POPL 2007 Nice, France
Specifications Haskell:
Specifications Haskell: ML:
Implementations Haskell:
Implementations Haskell: ML:
Generic Implementations Haskell:
Generic Implementations Haskell: ML:
Type Classes vs. Modules • Haskell type classes (Wadler and Blott, Jones, et al.): • Elegant account of ad-hoc polymorphism • May want different instances of integer equality to be canonical in different scopes • Not a substitute for a module system • ML modules (MacQueen, Harper, Leroy, et al.): • Explicit, fine-grained control over linking and abstraction • No support for implicit program construction
Our Proposal • Start with ML modules: • Classes are just signatures of a special form • Instances are just structures and functors of a special form • Allow programmers to designate certain instance modules as canonicalwithin a particular scope • No tradeoff necessary – Get the best of both worlds! • Have access to full-featured module system by default • Can hook into the type inference engine and make use of Haskell-style overloading, if/when you want to
Classes and Instances in ML • Great, but now how do we create the eq function?
Creating an Overloaded Function • We employ an overload mechanism: • This creates a “polymorphic value” eq, represented internally (in the semantics) as an implicit functor: • Analogous to Haskell’s qualified types:
Using eq • If we apply eq to some arguments of type int * int: • This initiates a demand for a canonical module of signature • But none exists ) Type error!
Making an Instance Canonical • Designate EqInt and EqProd as canonical in a certain scope:
Making an Instance Canonical • Now if we apply eq in that scope: • Then the above code typechecks and translates internally to: • Similar to evidence translation in Haskell: • Here we use modules as evidence
Class Hierarchies Haskell subclass declaration: How to support class hierarchies using modules?
Class Hierarchies Haskell subclass declaration: How to support class hierarchies using modules? • Use module hierarchies!
Composite Class Signatures • Instances of ORD are automatically computed frominstances of EQ and instances of LT
Associated Types • Proposed by Chakravarty et al. (2005) as an alternative to“functional dependencies” • Basic idea: Add type components to classes • Falls out naturally from modular framework • Associated types are just type components of class signatures other than the one called t • In Haskell, requires the introduction of “equality constraints” • In ML, these are just where type constraints
What Else is in the Paper • Other design points: • Coercions between implicit and explicit functors • Coherence in the presence of explicitly-scoped instances • Handling of overlapping instances • Type-theoretic formalization (details in the tech report): • Declarative elaboration semantics (a la Harper-Stone) • Type inference algorithm • Algorithm is sound, but not complete(due to problems inherited from both Haskell and ML) • Related work
Associated Types(Chakravarty et al. 05) • A function sumColl that sums the elements of a collectionwould have polymorphic type:
Haskell Approach • Beef up type classes: • Multi-parameter classes (Jones, Peyton Jones, et al.) • Constructor classes (Jones 95) • Functional dependencies (Jones 00) • Associated types (Chakravarty et al. 05) • …and more • Each extension brings classes closer to modules,but still no explicit control over linking • Only attempt at explicit control is“named instances” (Kahl and Scheffczyk 01)
Instance of Ord at Int Haskell:
Instance of Ord at Int Haskell: ML:
Instance of Ord at £ Haskell:
Instance of Ord at £ Haskell: ML:
Instance of Ord at £ Haskell: ML:
Computing a Composite Instance • Assuming LtInt and LtProd have been “used”, the canonical module of signature is