First-Class Subkinds in Haskell Wolfgang Jeltsch Recapitulation Subkinds needed First-Class Subkinds in Haskell Subkind emulation Closing subkinds Wolfgang Jeltsch TT¨ U K¨ uberneetika Instituut Teooriaseminar October 27, 2011
First-Class Overview Subkinds in Haskell Wolfgang Jeltsch Recapitulation Subkinds needed Recapitulation Subkind emulation Closing subkinds Subkinds needed Subkind emulation Closing subkinds
First-Class Overview Subkinds in Haskell Wolfgang Jeltsch Recapitulation Subkinds needed Recapitulation Subkind emulation Closing subkinds Subkinds needed Subkind emulation Closing subkinds
First-Class Record types Subkinds in Haskell Wolfgang Jeltsch ◮ record type is an application of a record scheme Recapitulation Subkinds needed to a style parameter, where the style denotes Subkind emulation a type-level function: Closing subkinds σ = X data X data ( ρ :& ϕ ) σ = ρ σ :& ϕ σ ◮ type synonym family App describes type-level function application: type family App ϕ α ◮ field scheme consists of a name and a sort: data ( ν ::: ς ) σ = ν := App σ ς ◮ families of related record types can be generated by applying the same scheme to different styles
First-Class Record scheme induction Subkinds in Haskell Wolfgang Jeltsch Recapitulation Subkinds needed class Record ρ where Subkind emulation Closing subkinds fold :: θ X → ( ∀ ρ ν ς . ( Record ρ ) ⇒ θ ρ → θ ( ρ :& ν ::: ς )) → θ ρ instance Record X where = f X fold f X instance ( Record ρ ) ⇒ Record ( ρ :& ν ::: ς ) where � � fold f X f (:&) = f (:&) fold f X f (:&)
First-Class The modify combinator Subkinds in Haskell ◮ combinator for modifying all fields of a record: Wolfgang Jeltsch Recapitulation modify ( X :& ν 1 := f 1 :& . . . :& ν n := f n ) Subkinds needed ( X :& ν 1 := x 1 :& . . . :& ν n := x n ) Subkind emulation = Closing subkinds X :& ν 1 := f 1 x 1 :& . . . :& ν n := f n x n ◮ type of modify : ( Record ρ ) ⇒ ρ Σ Mod → ρ Σ Plain → ρ Σ Plain ◮ record styles used in the type of modify : type instance App Σ Plain α = α type instance App Σ Mod α = α → α ◮ modify implemented as a fold application, using the following replacement for the θ -variable: type Θ modify ρ = ρ Σ Mod → ρ Σ Plain → ρ Σ Plain
First-Class Overview Subkinds in Haskell Wolfgang Jeltsch Recapitulation Subkinds needed Recapitulation Subkind emulation Closing subkinds Subkinds needed Subkind emulation Closing subkinds
First-Class The mapElems combinator Subkinds in Haskell ◮ conversion from arrays to lists: Wolfgang Jeltsch elems :: ( Ix ι ) ⇒ Array ι α → [ α ] Recapitulation Subkinds needed ◮ conversion from array records to list records: Subkind emulation mapElems ( X :& ν 1 := a 1 :& . . . :& ν n := a n ) Closing subkinds = X :& ν 1 := elems a 1 :& . . . :& ν n := elems a n ◮ sorts must denote pairs of an index and an element type ◮ pick some type constructor Π and encode ( ι, α ) as Π ι α ◮ let’s choose Array as our Π ◮ styles for the record argument and the list result: type instance App Σ Array ( Array ι α ) = Array ι α type instance App Σ List ( Array ι α ) = [ α ] ◮ type of mapElems : ( Record ρ ) ⇒ ρ Σ Array → ρ Σ List
First-Class Problems with this combinator Subkinds in Haskell ◮ mapElems can only work with sorts that are array types Wolfgang Jeltsch ◮ so the type Recapitulation ( Record ρ ) ⇒ ρ Σ Array → ρ Σ List Subkinds needed Subkind emulation is too general Closing subkinds ◮ implementation of mapElems based on fold : mapElems = fold f X f (:&) where f X = λ X → X f (:&) g = λ ( r :& ν := a ) → g r :& ν := elems a ◮ problem with this implementation: ◮ most general type of f (:&) : ∀ ρ ν ι α . ( Record ρ, Ix ι ) ⇒ Θ mapElems ρ → Θ mapElems ( ρ :& ν ::: Array ι α ) ◮ required type: ∀ ρ ν ς . ( Record ρ ) ⇒ Θ mapElems ρ → Θ mapElems ( ρ :& ν ::: ς )
First-Class Subkinds to the rescue Subkinds in Haskell Wolfgang Jeltsch ◮ introduce subkinds as the kind-level analog of subtypes Recapitulation ◮ subtypes of kind ∗ cover some types of kind ∗ Subkinds needed Subkind emulation ◮ examples of such subkinds: Closing subkinds Array all types Array ι α with ( Ix ι ) Map all types Map κ α with ( Ord κ ) and all types IntMap α ∗ all types of kind ∗ ◮ extend the Record class such that it allows for induction over all schemes whose sorts are of a given subkind ◮ define mapElems such that it only works for sorts of kind Array ◮ problem: no support for subkinds in present-day Haskell
First-Class Overview Subkinds in Haskell Wolfgang Jeltsch Recapitulation Subkinds needed Recapitulation Subkind emulation Closing subkinds Subkinds needed Subkind emulation Closing subkinds
First-Class Emulation of subkinds Subkinds in Haskell Wolfgang Jeltsch ◮ represent subkinds by types: Recapitulation data Ξ Array Subkinds needed Subkind emulation data Ξ Map Closing subkinds data Ξ ∗ ◮ ordinary parametric polymorphism can be used to emulate subkind polymorphism ◮ class Inhabitant that specifies subkind inhabitation: class Inhabitant ξ ς instance ( Ix ι ) ⇒ Inhabitant Ξ Array ( Array ι α ) instance ( Ord κ ) ⇒ Inhabitant Ξ Map ( Map κ α ) Inhabitant Ξ Map ( IntMap α ) instance instance Inhabitant Ξ ∗ α
First-Class Subkind support for records Subkinds in Haskell ◮ Record class with subkind support: Wolfgang Jeltsch Recapitulation class Record ξ ρ where Subkinds needed Subkind emulation fold :: θ X → Closing subkinds ( ∀ ρ ν ς . ( Record ξ ρ, Inhabitant ξ ς ) ⇒ θ ρ → θ ( ρ :& ν ::: ς )) → θ ρ instance Record ξ X where fold f X = f X instance ( Record ξ ρ, Inhabitant ξ ς ) ⇒ Record ξ ( ρ :& ν ::: ς ) where � � fold f X f (:&) = f (:&) fold f X f (:&) ◮ type of mapElems : ( Record Ξ Array ρ ) ⇒ ρ Σ Array → ρ Σ List
First-Class A problem with open classes Subkinds in Haskell Wolfgang Jeltsch ◮ from the definition of mapElems : Recapitulation f (:&) g = λ ( r :& ν := a ) → g r :& ν := elems a Subkinds needed ◮ most general type of f (:&) : Subkind emulation Closing subkinds ∀ ρ ν ι α . ( Record ρ, Ix ι ) ⇒ Θ mapElems ρ → Θ mapElems ( ρ :& ν ::: Array ι α ) ◮ required type: ∀ ρ ν ς . ( Record ρ, Inhabitant Ξ Array ς ) ⇒ Θ mapElems ρ → Θ mapElems ( ρ :& ν ::: ς ) ◮ required type still more general, since Inhabitant could be extended: instance Inhabitant Ξ Array Bool
First-Class Overview Subkinds in Haskell Wolfgang Jeltsch Recapitulation Subkinds needed Recapitulation Subkind emulation Closing subkinds Subkinds needed Subkind emulation Closing subkinds
First-Class Closing the Array subkind Subkinds in Haskell ◮ enforce that the set of all ς with ( Inhabitant Ξ Array ς ) Wolfgang Jeltsch is the set of all Array inhabitants Recapitulation ◮ realized by enforcing that Subkinds needed ∀ ς . ( Inhabitant Ξ Array ς ) ⇒ F ς Subkind emulation ∼ Closing subkinds = ∀ ς :: Array . F ς for all type-level functions F ◮ sufficient to enforce this for all types F :: ∗ → ∗ , since for every type-level function there is an isomorphic newtype wrapper ◮ expressing universal quantification over Array inhabitants in Haskell: ∀ ς :: Array . F ς = ∀ ι α . ( Ix ι ) ⇒ F ( Array ι α )
First-Class Universal quantification over Map inhabitants Subkinds in Haskell Wolfgang Jeltsch ◮ Map is the sum of two subkinds: Recapitulation Map 1 all types Map κ α with ( Ord κ ) Subkinds needed Map 2 all types IntMap α Subkind emulation ◮ universal quantification can be expressed Closing subkinds for both subkinds: ( ∀ ς :: Map 1 . F ς ) = ( ∀ κ α . ( Ord κ ) ⇒ F ( Map κ α )) ( ∀ ς :: Map 2 . F ς ) = ( ∀ α . F ( IntMap α )) ◮ expressing universal quantification for Map : ∀ ς :: Map . F ς = ( ∀ κ α . ( Ord κ ) ⇒ F ( Map κ α ) , ∀ α . F ( IntMap α ))
First-Class Closing arbitrary subkinds Subkinds in Haskell ◮ introduce a data family All that denotes universal Wolfgang Jeltsch quantification for all subkind representations: Recapitulation data family All ξ :: ( ∗ → ∗ ) → ∗ Subkinds needed ◮ add an instance declaration for every subkind: Subkind emulation data instance Closing subkinds All Ξ Array ϕ = All Array ( ∀ ι α . ( Ix ι ) ⇒ ϕ ( Array ι α )) data instance All Ξ Map ϕ = All Map ( ∀ κ α . ( Ord κ ) ⇒ ϕ ( Map κ α )) ( ∀ α . ϕ ( IntMap α )) data instance All Ξ ∗ ϕ = All ∗ ( ∀ α . ϕ α ) ◮ enforce the isomorphism ( ∀ ς . ( Inhabitant ξ ς ) ⇒ ϕ ς ) ∼ = ( All ξ ϕ ) by requiring the implementation of conversion functions
First-Class Forward conversion Subkinds in Haskell Wolfgang Jeltsch ◮ introduce a class of all subkind representations Recapitulation with a method for forward conversion: Subkinds needed class Kind ξ where Subkind emulation closed :: ( ∀ ς . ( Inhabitant ξ ς ) ⇒ ϕ ς ) → All ξ ϕ Closing subkinds ◮ instance declarations: instance Kind Ξ Array where closed x = All Array x instance Kind Ξ Map where closed x = All Map x x instance Kind Ξ ∗ where closed x = All ∗ x ◮ add a context to the Record class: class ( Kind ξ ) ⇒ Record ξ ρ where . . .
Recommend
More recommend