-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Open records using closed type families. -- @package CTRex @version 0.6 -- | This module implements extensible records using closed type famillies. -- -- See the examples. -- -- Lists of (label,type) pairs are kept sorted thereby ensuring that { x -- = 0, y = 0 } and { y = 0, x = 0 } have the same type. -- -- In this way we can implement standard type classes such as Show, Eq, -- Ord and Bounded for open records, given that all the elements of the -- open record satify the constraint. module Data.OpenRecords -- | A label data Label (s :: Symbol) Label :: Label -- | This class gives the integer associated with a type-level symbol. -- There are instances of the class for every concrete literal: "hello", -- etc. -- -- Since: 4.7.0.0 class KnownSymbol (n :: Symbol) -- | A record with row r. data Rec (r :: Row *) -- | The kind of rows. This type is only used as a datakind. A row is a -- typelevel entity telling us which symbols are associated with which -- types. data Row a -- | The empty record empty :: Rec Empty -- | Type level variant of empty -- | Record extension. The row may already contain the label, in which case -- the origin value can be obtained after restriction (.-) with -- the label. extend :: KnownSymbol l => Label l -> a -> Rec r -> Rec (Extend l a r) -- | Record extension without shadowing. The row may not already contain -- label l. extendUnique :: (KnownSymbol l, r :\ l) => Label l -> a -> Rec r -> Rec (Extend l a r) -- | Type level operations of extend and extendUnique -- | Rename a label. The row may already contain the new label , in which -- case the origin value can be obtained after restriction (.-) -- with the new label. rename :: (KnownSymbol l, KnownSymbol l') => Label l -> Label l' -> Rec r -> Rec (Rename l l' r) -- | Rename a label. The row may not already contain the new label. renameUnique :: (KnownSymbol l, KnownSymbol l', r :\ l') => Label l -> Label l' -> Rec r -> Rec (Rename l l' r) -- | Type level operation of rename and renameUnique -- | Record restriction. Delete the label l from the record. (.-) :: KnownSymbol l => Rec r -> Label l -> Rec (r :- l) -- | Type level operation of .- -- | Update the value associated with the label. update :: KnownSymbol l => Label l -> r :! l -> Rec r -> Rec r -- | Record selection (.!) :: KnownSymbol l => Rec r -> Label l -> r :! l -- | Type level operation of .! -- | Record union (not commutative) (.++) :: Rec l -> Rec r -> Rec (l :++ r) -- | Type level operation of .++ -- | Record disjoint union (commutative) (.+) :: Disjoint l r => Rec l -> Rec r -> Rec (l :+ r) -- | Type level operation of .+ -- | Does the row lack (i.e. it has not) the specified label? type (:\) r l = LacksP l r ~ LabelUnique l -- | Are the two rows disjoint? (i.e. their sets of labels are disjoint) type Disjoint l r = DisjointR l r ~ IsDisjoint class Labels (r :: Row *) labels :: Labels r => Rec r -> [String] -- | If the constaint c holds for all elements in the row -- r, then the methods in this class are available. class Forall (r :: Row *) (c :: * -> Constraint) rinit :: Forall r c => CWit c -> (forall a. c a => a) -> Rec r erase :: Forall r c => CWit c -> (forall a. c a => a -> b) -> Rec r -> [b] eraseZip :: Forall r c => CWit c -> (forall a. c a => a -> a -> b) -> Rec r -> Rec r -> [b] -- | A witness of a constraint. For use like this rinit (CWit :: CWit -- Bounded) minBound data CWit (c :: * -> Constraint) data FWit (f :: * -> *) -- | Here we provide a datatype for denoting record operations. Use -- .| to actually apply the operations. -- -- This allows us to chain operations with nicer syntax. For example we -- can write: -- --
-- p :<-| z .| y :<- 'b' .| z :!= False .| x := 2 .| y := 'a' .| empty ---- -- Which results in: -- --
-- { p=False, x=2, y='b' }
--
--
-- Without this sugar, we would have written it like this:
--
-- -- rename z p $ update y 'b' $ extendUnique z False $ extend x 2 $ extend y 'a' empty ---- --
-- "p" ::<-| "z" :| RUp :| "z" ::= Bool :| "x" ::= Double :| "y" ::= Char :| Empty ---- -- As the type of the expression: -- --
-- p :<-| z .| y :<- 'b' .| z :!= False .| x := 2 .| y := 'a' .| empty ---- -- Without this sugar, we would have written it like this: -- --
-- Rename "p" "z" (Extend "z" Bool (Extend x Double (Extend "x" Int Empty))) ---- -- Of course, we can also just write: -- --
-- "p" ::= Bool :| "x" ::= Double :| "y" ::= Int :| Empty ---- -- instead, doing the computation ourselves, or even let the type infer. -- -- data RowOp (a :: *) RUp :: RowOp a (::=) :: Symbol -> a -> RowOp a (::<-|) :: Symbol -> Symbol -> RowOp a -- | Apply an operation to a record. (.|) :: c r => RecOp c ro -> Rec r -> Rec (ro :| r) -- | Apply a (typelevel) operation to a row. Type level operation of -- .| instance Forall r Bounded => Bounded (Rec r) instance (Eq (Rec r), Forall r Ord) => Ord (Rec r) instance Forall r Eq => Eq (Rec r) instance (Labels r, Forall r Show) => Show (Rec r) instance (KnownSymbol l, RZipt t1 t2) => RZipt ((l ':-> v1) : t1) ((l ':-> v2) : t2) instance RZipt '[] '[] instance RZipt r1 r2 => RowZip ('R r1) ('R r2) instance (KnownSymbol l, Forall ('R t) c, c a) => Forall ('R ((l ':-> a) : t)) c instance Forall ('R '[]) c instance (KnownSymbol l, c v, RMapc c f t) => RMapc c f ((l ':-> v) : t) instance RMapc c f '[] instance RMapc c f r => RowMapC c f ('R r) instance (KnownSymbol l, RowMapx f t) => RowMapx f ((l ':-> v) : t) instance RowMapx f '[] instance RowMapx f r => RowMap f ('R r) instance (KnownSymbol l, Labels ('R t)) => Labels ('R ((l ':-> v) : t)) instance Labels ('R '[]) instance (r :! l) ~ a => HasType l a r instance r :\ l => Lacks l r instance NoConstr a instance KnownSymbol s => Show (Label s)