-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Open Records and Variants -- -- This package uses closed type families and type literals to implement -- open records and variants. The core is based off of the CTRex -- package, but it additionally includes polymorphic variants and a -- number of additional functions. That said, it is not a proper superset -- of CTRex as it specifically forbids records from having more than one -- element of the same label. @package row-types @version 0.2.3.0 -- | This module implements the internals of open records and variants. module Data.Row.Internal -- | 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. newtype Row a -- | A row is a list of symbol-to-type pairs that should always be sorted -- lexically by the symbol. The constructor is exported here (because -- this is an internal module) but should not be exported elsewhere. R :: [LT a] -> Row a -- | A label data Label (s :: Symbol) Label :: Label -- | This class gives the string associated with a type-level symbol. There -- are instances of the class for every concrete literal: "hello", etc. class KnownSymbol (n :: Symbol) -- | The kind of elements of rows. Each element is a label and its -- associated type. data LT a (:->) :: Symbol -> a -> LT a -- | Type level version of empty type Empty = R '[] -- | Elements stored in a Row type are usually hidden. data HideType [HideType] :: a -> HideType -- | Type level Row extension -- | Type level Row modification -- | Type level row renaming -- | Does the row lack (i.e. it does not have) the specified label? -- | Type level label fetching -- | Type level Row element removal -- | Type level Row append -- | Type level Row difference. That is, l .\\ r is the row -- remaining after removing any matching elements of r from -- l. -- | A type level way to create a singleton Row. type (l :: Symbol) .== (a :: k) = Extend l a Empty -- | The minimum join of the two rows. -- | Alias for .\. It is a class rather than an alias, so that it -- can be partially applied. class Lacks (l :: Symbol) (r :: Row *) -- | Alias for (r .! l) ≈ a. It is a class rather than an alias, -- so that it can be partially applied. class (r .! l ≈ a) => HasType l a r -- | The labels in a Row. -- | Return a list of the labels in a row type. labels :: forall ρ c s. (IsString s, Forall ρ c) => [s] -- | Return a list of the labels in a row type and is specialized to the -- Unconstrained1 constraint. labels' :: forall ρ s. (IsString s, Forall ρ Unconstrained1) => [s] -- | Any structure over a row in which every element is similarly -- constrained can be metamorphized into another structure over the same -- row. class Forall (r :: Row k) (c :: k -> Constraint) -- | A metamorphism is an unfold followed by a fold. This one is for -- product-like row-types (e.g. Rec). metamorph :: forall (f :: Row k -> *) (g :: Row k -> *) (h :: k -> *). Forall r c => Proxy h -> (f Empty -> g Empty) -> (forall ℓ τ ρ. (KnownSymbol ℓ, c τ) => Label ℓ -> f ( 'R (ℓ :-> τ : ρ)) -> (h τ, f ( 'R ρ))) -> (forall ℓ τ ρ. (KnownSymbol ℓ, c τ, FoldStep ℓ τ ρ) => Label ℓ -> h τ -> g ( 'R ρ) -> g ( 'R (ℓ :-> τ : ρ))) -> f r -> g r -- | A metamorphism is an unfold followed by a fold. This one is for -- sum-like row-types (e.g. Var). metamorph' :: forall (f :: Row k -> *) (g :: Row k -> *) (h :: k -> *). Forall r c => Proxy h -> (f Empty -> g Empty) -> (forall ℓ τ ρ. (KnownSymbol ℓ, c τ) => Label ℓ -> f ( 'R (ℓ :-> τ : ρ)) -> Either (h τ) (f ( 'R ρ))) -> (forall ℓ τ ρ. (KnownSymbol ℓ, c τ, FoldStep ℓ τ ρ) => Label ℓ -> Either (h τ) (g ( 'R ρ)) -> g ( 'R (ℓ :-> τ : ρ))) -> f r -> g r -- | Any structure over two rows in which every element of both rows -- satisfies the given constraint can be metamorphized into another -- structure over both of the rows. TODO: Perhaps it should be over two -- constraints? But this hasn't seemed necessary in practice. class Forall2 (r1 :: Row k) (r2 :: Row k) (c :: k -> Constraint) -- | A metamorphism is a fold followed by an unfold. Here, we fold both of -- the inputs. metamorph2 :: forall (f :: Row k -> *) (g :: Row k -> *) (h :: Row k -> Row k -> *) (f' :: k -> *) (g' :: k -> *). Forall2 r1 r2 c => Proxy f' -> Proxy g' -> (f Empty -> g Empty -> h Empty Empty) -> (forall ℓ τ1 τ2 ρ1 ρ2. (KnownSymbol ℓ, c τ1, c τ2) => Label ℓ -> f ( 'R (ℓ :-> τ1 : ρ1)) -> g ( 'R (ℓ :-> τ2 : ρ2)) -> ((f' τ1, f ( 'R ρ1)), (g' τ2, g ( 'R ρ2)))) -> (forall ℓ τ1 τ2 ρ1 ρ2. (KnownSymbol ℓ, c τ1, c τ2) => Label ℓ -> f' τ1 -> g' τ2 -> h ( 'R ρ1) ( 'R ρ2) -> h ( 'R (ℓ :-> τ1 : ρ1)) ( 'R (ℓ :-> τ2 : ρ2))) -> f r1 -> g r2 -> h r1 r2 -- | A null constraint of one argument class Unconstrained1 a -- | A helper function for showing labels show' :: (IsString s, Show a) => a -> s -- | A helper function to turn a Label directly into Text. toKey :: forall s. KnownSymbol s => Label s -> Text -- | A lower fixity operator for type equality type a ≈ b = a ~ b -- | A convenient way to provide common, easy constraints type WellBehaved ρ = (Forall ρ Unconstrained1, AllUniqueLabels ρ) -- | Are all of the labels in this Row unique? -- | Zips two rows together to create a Row of the pairs. The two rows must -- have the same set of labels. -- | Map a type level function over a Row. -- | Is the first row a subset of the second? -- | A type synonym for disjointness. type Disjoint l r = (WellBehaved l, WellBehaved r, Subset l (l .+ r), Subset r (l .+ r), l .+ r .\\ l ≈ r, l .+ r .\\ r ≈ l) -- | This allows us to derive a `Forall (Map f r) ..` from a `Forall r ..`. mapForall :: forall f c ρ. Forall ρ c :- Forall (Map f ρ) (IsA c f) -- | Allow any Forall over a row-type, be usable for -- Unconstrained1. freeForall :: forall r c. Forall r c :- Forall r Unconstrained1 -- | Map preserves uniqueness of labels. uniqueMap :: forall f ρ. AllUniqueLabels ρ :- AllUniqueLabels (Map f ρ) -- | A class to capture the idea of As so that it can be partially -- applied in a context. class IsA c f a as :: IsA c f a => As c f a -- | This data type is used to for its ability to existentially bind a type -- variable. Particularly, it says that for the type a, there -- exists a t such that 'a ~ f t' and 'c t' holds. data As c f a [As] :: forall c f a t. (a ~ f t, c t) => As c f a -- | Proof that the given label is a valid candidate for the next step in a -- metamorph fold, i.e. it's not in the list yet and, when sorted, will -- be placed at the head. type FoldStep ℓ τ ρ = Inject (ℓ :-> τ) ρ ≈ ℓ :-> τ : ρ instance forall k (r :: Data.Row.Internal.Row k) (l :: GHC.Types.Symbol) (a :: k). ((r Data.Row.Internal..! l) Data.Row.Internal.≈ a) => Data.Row.Internal.HasType l a r instance forall k (c :: k -> GHC.Types.Constraint). Data.Row.Internal.Forall ('Data.Row.Internal.R '[]) c instance forall k (ℓ :: GHC.Types.Symbol) (c :: k -> GHC.Types.Constraint) (τ :: k) (ρ :: [Data.Row.Internal.LT k]). (GHC.TypeLits.KnownSymbol ℓ, c τ, Data.Row.Internal.FoldStep ℓ τ ρ, Data.Row.Internal.Forall ('Data.Row.Internal.R ρ) c) => Data.Row.Internal.Forall ('Data.Row.Internal.R ((ℓ 'Data.Row.Internal.:-> τ) : ρ)) c instance (x Data.Row.Internal.≈ y) => GHC.OverloadedLabels.IsLabel x (Data.Row.Internal.Label y) instance (r Data.Row.Internal..\ l) => Data.Row.Internal.Lacks l r instance forall k (a :: k). Data.Row.Internal.Unconstrained1 a instance Data.Row.Internal.Unconstrained instance forall k (c :: k -> GHC.Types.Constraint). Data.Row.Internal.Forall2 ('Data.Row.Internal.R '[]) ('Data.Row.Internal.R '[]) c instance forall a (ℓ :: GHC.Types.Symbol) (c :: a -> GHC.Types.Constraint) (τ1 :: a) (τ2 :: a) (ρ1 :: [Data.Row.Internal.LT a]) (ρ2 :: [Data.Row.Internal.LT a]). (GHC.TypeLits.KnownSymbol ℓ, c τ1, c τ2, Data.Row.Internal.Forall2 ('Data.Row.Internal.R ρ1) ('Data.Row.Internal.R ρ2) c) => Data.Row.Internal.Forall2 ('Data.Row.Internal.R ((ℓ 'Data.Row.Internal.:-> τ1) : ρ1)) ('Data.Row.Internal.R ((ℓ 'Data.Row.Internal.:-> τ2) : ρ2)) c instance forall k1 k2 (c :: k2 -> GHC.Types.Constraint) (a :: k2) (f :: k2 -> k1). c a => Data.Row.Internal.IsA c f (f a) instance GHC.TypeLits.KnownSymbol s => GHC.Show.Show (Data.Row.Internal.Label s) -- | This module implements extensible records using closed type famillies. -- -- See Examples.hs for 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.Row.Records -- | A label data Label (s :: Symbol) Label :: Label -- | This class gives the string associated with a type-level symbol. There -- are instances of the class for every concrete literal: "hello", etc. class KnownSymbol (n :: Symbol) -- | Are all of the labels in this Row unique? -- | A convenient way to provide common, easy constraints type WellBehaved ρ = (Forall ρ Unconstrained1, AllUniqueLabels ρ) -- | 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 -- | Type level version of empty type Empty = R '[] -- | A lower fixity operator for type equality type a ≈ b = a ~ b -- | The empty record empty :: Rec Empty -- | A type level way to create a singleton Row. type (l :: Symbol) .== (a :: k) = Extend l a Empty -- | The singleton record (.==) :: KnownSymbol l => Label l -> a -> Rec (l .== a) infix 7 .== -- | A pattern for the singleton record; can be used to both destruct a -- record when in a pattern position or construct one in an expression -- position. infix 7 :== -- | Turns a singleton record into a pair of the label and value. unSingleton :: forall l a. KnownSymbol l => Rec (l .== a) -> (Label l, a) -- | Initialize a record with a default value at each label. default' :: forall c ρ. (Forall ρ c, AllUniqueLabels ρ) => (forall a. c a => a) -> Rec ρ -- | Initialize a record with a default value at each label; works over an -- Applicative. defaultA :: forall c f ρ. (Applicative f, Forall ρ c, AllUniqueLabels ρ) => (forall a. c a => f a) -> f (Rec ρ) -- | Initialize a record, where each value is determined by the given -- function over the label at that value. fromLabels :: forall c ρ. (Forall ρ c, AllUniqueLabels ρ) => (forall l a. (KnownSymbol l, c a) => Label l -> a) -> Rec ρ -- | Initialize a record, where each value is determined by the given -- function over the label at that value. This function works over an -- Applicative. fromLabelsA :: forall c f ρ. (Applicative f, Forall ρ c, AllUniqueLabels ρ) => (forall l a. (KnownSymbol l, c a) => Label l -> f a) -> f (Rec ρ) -- | Initialize a record that is produced by a Map. fromLabelsMapA :: forall c f g ρ. (Applicative f, Forall ρ c, AllUniqueLabels ρ) => (forall l a. (KnownSymbol l, c a) => Label l -> f (g a)) -> f (Rec (Map g ρ)) -- | Record extension. The row may already contain the label, in which case -- the origin value can be obtained after restriction (.-) with -- the label. extend :: forall a l r. KnownSymbol l => Label l -> a -> Rec r -> Rec (Extend l a r) -- | Type level Row extension -- | Alias for .\. It is a class rather than an alias, so that it -- can be partially applied. class Lacks (l :: Symbol) (r :: Row *) -- | Does the row lack (i.e. it does not have) the specified label? -- | Type level Row element removal -- | Record restriction. Remove the label l from the record. (.-) :: KnownSymbol l => Rec r -> Label l -> Rec (r .- l) infixl 6 .- -- | Arbitrary record restriction. Turn a record into a subset of itself. restrict :: forall r r'. (Forall r Unconstrained1, Subset r r') => Rec r' -> Rec r -- | Split a record into two sub-records. split :: forall s r. (Forall s Unconstrained1, Subset s r) => Rec r -> (Rec s, Rec (r .\\ s)) -- | Update the value associated with the label. update :: (KnownSymbol l, r .! l ≈ a) => Label l -> a -> Rec r -> Rec r -- | Focus on the value associated with the label. focus :: (Functor f, KnownSymbol l) => Label l -> (r .! l -> f a) -> Rec r -> f (Rec (Modify l a r)) -- | Focus on a sub-record multifocus :: forall u v r f. (Functor f, Disjoint u r, Disjoint v r) => (Rec u -> f (Rec v)) -> Rec (u .+ r) -> f (Rec (v .+ r)) -- | Type level Row modification -- | Rename a label. rename :: (KnownSymbol l, KnownSymbol l') => Label l -> Label l' -> Rec r -> Rec (Rename l l' r) -- | Type level row renaming -- | Alias for (r .! l) ≈ a. It is a class rather than an alias, -- so that it can be partially applied. class (r .! l ≈ a) => HasType l a r -- | Type level label fetching -- | Record selection (.!) :: KnownSymbol l => Rec r -> Label l -> r .! l -- | Type level Row append -- | Record disjoint union (commutative) (.+) :: Rec l -> Rec r -> Rec (l .+ r) infixl 6 .+ -- | A type synonym for disjointness. type Disjoint l r = (WellBehaved l, WellBehaved r, Subset l (l .+ r), Subset r (l .+ r), l .+ r .\\ l ≈ r, l .+ r .\\ r ≈ l) -- | A pattern version of record union, for use in pattern matching. infixl 6 :+ -- | Convert a record to a native Haskell type. toNative :: forall t ρ. (Generic t, ToNative (Rep t) ρ) => Rec ρ -> t -- | Convert a Haskell record to a row-types Rec. fromNative :: forall t ρ. (Generic t, FromNative (Rep t) ρ) => t -> Rec ρ -- | Map a type level function over a Row. -- | A function to map over a record given a constraint. map :: forall c f r. Forall r c => (forall a. c a => a -> f a) -> Rec r -> Rec (Map f r) -- | A function to map over a record given no constraint. map' :: forall f r. Forall r Unconstrained1 => (forall a. a -> f a) -> Rec r -> Rec (Map f r) -- | Lifts a natrual transformation over a record. In other words, it acts -- as a record transformer to convert a record of f a values to -- a record of g a values. If no constraint is needed, -- instantiate the first type argument with Unconstrained1 or use -- transform'. transform :: forall c r (f :: * -> *) (g :: * -> *). Forall r c => (forall a. c a => f a -> g a) -> Rec (Map f r) -> Rec (Map g r) -- | A version of transform for when there is no constraint. transform' :: forall r (f :: * -> *) (g :: * -> *). Forall r Unconstrained1 => (forall a. f a -> g a) -> Rec (Map f r) -> Rec (Map g r) -- | Any structure over a row in which every element is similarly -- constrained can be metamorphized into another structure over the same -- row. class Forall (r :: Row k) (c :: k -> Constraint) -- | A standard fold erase :: forall c ρ b. Forall ρ c => (forall a. c a => a -> b) -> Rec ρ -> [b] -- | A fold with labels eraseWithLabels :: forall c ρ s b. (Forall ρ c, IsString s) => (forall a. c a => a -> b) -> Rec ρ -> [(s, b)] -- | A fold over two row type structures at once eraseZip :: forall c ρ b. Forall ρ c => (forall a. c a => a -> a -> b) -> Rec ρ -> Rec ρ -> [b] -- | Turns a record into a HashMap from values representing the -- labels to the values of the record. eraseToHashMap :: forall c r s b. (IsString s, Eq s, Hashable s, Forall r c) => (forall a. c a => a -> b) -> Rec r -> HashMap s b -- | Zips two rows together to create a Row of the pairs. The two rows must -- have the same set of labels. -- | Zips together two records that have the same set of labels. zip :: forall r1 r2. Forall2 r1 r2 Unconstrained1 => Rec r1 -> Rec r2 -> Rec (Zip r1 r2) -- | Applicative sequencing over a record. sequence :: forall f r. (Forall r Unconstrained1, Applicative f) => Rec (Map f r) -> f (Rec r) -- | A version of sequence in which the constraint for Forall -- can be chosen. sequence' :: forall f r c. (Forall r c, Applicative f) => Rec (Map f r) -> f (Rec r) -- | Convert from a record where two functors have been mapped over the -- types to one where the composition of the two functors is mapped over -- the types. compose :: forall (f :: * -> *) (g :: * -> *) r. Forall r Unconstrained1 => Rec (Map f (Map g r)) -> Rec (Map (Compose f g) r) -- | Convert from a record where the composition of two functors have been -- mapped over the types to one where the two functors are mapped -- individually one at a time over the types. uncompose :: forall (f :: * -> *) (g :: * -> *) r. Forall r Unconstrained1 => Rec (Map (Compose f g) r) -> Rec (Map f (Map g r)) -- | A version of compose in which the constraint for Forall -- can be chosen. compose' :: forall c (f :: * -> *) (g :: * -> *) (r :: Row *). Forall r c => Rec (Map f (Map g r)) -> Rec (Map (Compose f g) r) -- | A version of uncompose in which the constraint for -- Forall can be chosen. uncompose' :: forall c (f :: * -> *) (g :: * -> *) r. Forall r c => Rec (Map (Compose f g) r) -> Rec (Map f (Map g r)) -- | Return a list of the labels in a row type. labels :: forall ρ c s. (IsString s, Forall ρ c) => [s] -- | Return a list of the labels in a row type and is specialized to the -- Unconstrained1 constraint. labels' :: forall ρ s. (IsString s, Forall ρ Unconstrained1) => [s] -- | Removes a label from the record but does not remove the underlying -- value. -- -- This is faster than regular record removal (.-) but should only -- be used when either: the record will never be merged with another -- record again, or a new value will soon be placed into the record at -- this label (as in, an update that is split over two commands). -- -- If the resulting record is then merged (with .+) with another -- record that contains a value at that label, an "impossible" error will -- occur. unsafeRemove :: KnownSymbol l => Label l -> Rec r -> Rec (r .- l) -- | A helper function for unsafely adding an element to the front of a -- record. This can cause the resulting record to be malformed, for -- instance, if the record already contains labels that are -- lexicographically before the given label. Realistically, this function -- should only be used when writing calls to metamorph. unsafeInjectFront :: KnownSymbol l => Label l -> a -> Rec (R r) -> Rec (R (l :-> a : r)) instance forall k (cs :: k -> *) (ρ :: Data.Row.Internal.Row *) (m :: GHC.Generics.Meta). Data.Row.Records.FromNative cs ρ => Data.Row.Records.FromNative (GHC.Generics.D1 m cs) ρ instance forall k (cs :: k -> *) (ρ :: Data.Row.Internal.Row *) (m :: GHC.Generics.Meta). Data.Row.Records.FromNative cs ρ => Data.Row.Records.FromNative (GHC.Generics.C1 m cs) ρ instance (GHC.TypeLits.KnownSymbol name, ρ Data.Row.Internal.≈ (name Data.Row.Internal..== t)) => Data.Row.Records.FromNative (GHC.Generics.S1 ('GHC.Generics.MetaSel ('GHC.Base.Just name) p s l) (GHC.Generics.Rec0 t)) ρ instance forall k (l :: k -> *) (ρ₁ :: Data.Row.Internal.Row *) (r :: k -> *) (ρ₂ :: Data.Row.Internal.Row *) (ρ :: Data.Row.Internal.Row *). (Data.Row.Records.FromNative l ρ₁, Data.Row.Records.FromNative r ρ₂, ρ Data.Row.Internal.≈ (ρ₁ Data.Row.Internal..+ ρ₂)) => Data.Row.Records.FromNative (l GHC.Generics.:*: r) ρ instance forall k (cs :: k -> *) (ρ :: Data.Row.Internal.Row *) (m :: GHC.Generics.Meta). Data.Row.Records.ToNative cs ρ => Data.Row.Records.ToNative (GHC.Generics.D1 m cs) ρ instance forall k (cs :: k -> *) (ρ :: Data.Row.Internal.Row *) (m :: GHC.Generics.Meta). Data.Row.Records.ToNative cs ρ => Data.Row.Records.ToNative (GHC.Generics.C1 m cs) ρ instance (GHC.TypeLits.KnownSymbol name, (ρ Data.Row.Internal..! name) Data.Row.Internal.≈ t) => Data.Row.Records.ToNative (GHC.Generics.S1 ('GHC.Generics.MetaSel ('GHC.Base.Just name) p s l) (GHC.Generics.Rec0 t)) ρ instance forall k (l :: k -> *) (ρ :: Data.Row.Internal.Row *) (r :: k -> *). (Data.Row.Records.ToNative l ρ, Data.Row.Records.ToNative r ρ) => Data.Row.Records.ToNative (l GHC.Generics.:*: r) ρ instance Data.Row.Internal.Forall r GHC.Show.Show => GHC.Show.Show (Data.Row.Records.Rec r) instance Data.Row.Internal.Forall r GHC.Classes.Eq => GHC.Classes.Eq (Data.Row.Records.Rec r) instance (Data.Row.Internal.Forall r GHC.Classes.Eq, Data.Row.Internal.Forall r GHC.Classes.Ord) => GHC.Classes.Ord (Data.Row.Records.Rec r) instance (Data.Row.Internal.Forall r GHC.Enum.Bounded, Data.Row.Internal.AllUniqueLabels r) => GHC.Enum.Bounded (Data.Row.Records.Rec r) instance Data.Row.Internal.Forall r Control.DeepSeq.NFData => Control.DeepSeq.NFData (Data.Row.Records.Rec r) -- | This module implements extensible variants using closed type families. module Data.Row.Variants -- | A label data Label (s :: Symbol) Label :: Label -- | This class gives the string associated with a type-level symbol. There -- are instances of the class for every concrete literal: "hello", etc. class KnownSymbol (n :: Symbol) -- | Are all of the labels in this Row unique? -- | A convenient way to provide common, easy constraints type WellBehaved ρ = (Forall ρ Unconstrained1, AllUniqueLabels ρ) -- | The variant type. data Var (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 -- | Type level version of empty type Empty = R '[] -- | A lower fixity operator for type equality type a ≈ b = a ~ b -- | Alias for (r .! l) ≈ a. It is a class rather than an alias, -- so that it can be partially applied. class (r .! l ≈ a) => HasType l a r -- | A pattern for variants; can be used to both destruct a variant when in -- a pattern position or construct one in an expression position. -- | A quick constructor to create a singleton variant. singleton :: KnownSymbol l => Label l -> a -> Var (l .== a) -- | Initialize a variant from a producer function that accepts labels. If -- this function returns more than one possibility, then one is chosen -- arbitrarily to be the value in the variant. fromLabels :: forall c ρ f. (Alternative f, Forall ρ c, AllUniqueLabels ρ) => (forall l a. (KnownSymbol l, c a) => Label l -> f a) -> f (Var ρ) -- | Does the row lack (i.e. it does not have) the specified label? -- | Alias for .\. It is a class rather than an alias, so that it -- can be partially applied. class Lacks (l :: Symbol) (r :: Row *) -- | The minimum join of the two rows. -- | Make the variant arbitrarily more diverse. diversify :: forall r' r. Var r -> Var (r .\/ r') -- | Type level Row append -- | If the variant exists at the given label, update it to the given -- value. Otherwise, do nothing. update :: (KnownSymbol l, r .! l ≈ a) => Label l -> a -> Var r -> Var r -- | If the variant exists at the given label, focus on the value -- associated with it. Otherwise, do nothing. focus :: (Applicative f, KnownSymbol l) => Label l -> (r .! l -> f a) -> Var r -> f (Var (Modify l a r)) -- | Type level Row modification -- | Rename the given label. rename :: (KnownSymbol l, KnownSymbol l') => Label l -> Label l' -> Var r -> Var (Rename l l' r) -- | Type level row renaming -- | A Variant with no options is uninhabited. impossible :: Var Empty -> a -- | Convert a variant into either the value at the given label or a -- variant without that label. This is the basic variant destructor. trial :: KnownSymbol l => Var r -> Label l -> Either (r .! l) (Var (r .- l)) -- | A version of trial that ignores the leftover variant. trial' :: KnownSymbol l => Var r -> Label l -> Maybe (r .! l) -- | A trial over multiple types multiTrial :: forall x y. (AllUniqueLabels x, Forall (y .\\ x) Unconstrained1) => Var y -> Either (Var x) (Var (y .\\ x)) -- | A convenient function for using view patterns when dispatching -- variants. For example: -- --
--   myShow :: Var ("y" '::= String :| "x" '::= Int :| Empty) -> String
--   myShow (view x -> Just n) = "Int of "++show n
--   myShow (view y -> Just s) = "String of "++s
--   
view :: KnownSymbol l => Label l -> Var r -> Maybe (r .! l) -- | Arbitrary variant restriction. Turn a variant into a subset of itself. restrict :: forall r r'. (WellBehaved r, Subset r r') => Var r' -> Maybe (Var r) -- | Split a variant into two sub-variants. split :: forall s r. (WellBehaved s, Subset s r) => Var r -> Either (Var s) (Var (r .\\ s)) -- | Type level label fetching -- | Type level Row element removal -- | Type level Row difference. That is, l .\\ r is the row -- remaining after removing any matching elements of r from -- l. -- | A type level way to create a singleton Row. type (l :: Symbol) .== (a :: k) = Extend l a Empty -- | Map a type level function over a Row. -- | A function to map over a variant given a constraint. map :: forall c f r. Forall r c => (forall a. c a => a -> f a) -> Var r -> Var (Map f r) -- | A function to map over a variant given no constraint. map' :: forall f r. Forall r Unconstrained1 => (forall a. a -> f a) -> Var r -> Var (Map f r) -- | Lifts a natrual transformation over a variant. In other words, it acts -- as a variant transformer to convert a variant of f a values -- to a variant of g a values. If no constraint is needed, -- instantiate the first type argument with Unconstrained1. transform :: forall r c (f :: * -> *) (g :: * -> *). Forall r c => (forall a. c a => f a -> g a) -> Var (Map f r) -> Var (Map g r) -- | A form of transformC that doesn't have a constraint on -- a transform' :: forall r (f :: * -> *) (g :: * -> *). Forall r Unconstrained1 => (forall a. f a -> g a) -> Var (Map f r) -> Var (Map g r) -- | Any structure over a row in which every element is similarly -- constrained can be metamorphized into another structure over the same -- row. class Forall (r :: Row k) (c :: k -> Constraint) -- | A standard fold erase :: forall c ρ b. Forall ρ c => (forall a. c a => a -> b) -> Var ρ -> b -- | A fold with labels eraseWithLabels :: forall c ρ s b. (Forall ρ c, IsString s) => (forall a. c a => a -> b) -> Var ρ -> (s, b) -- | A fold over two row type structures at once eraseZip :: forall c ρ b. Forall ρ c => (forall a. c a => a -> a -> b) -> Var ρ -> Var ρ -> Maybe b -- | Applicative sequencing over a variant sequence :: forall f r. (Forall r Unconstrained1, Applicative f) => Var (Map f r) -> f (Var r) -- | Convert from a variant where two functors have been mapped over the -- types to one where the composition of the two functors is mapped over -- the types. compose :: forall (f :: * -> *) (g :: * -> *) r. Forall r Unconstrained1 => Var (Map f (Map g r)) -> Var (Map (Compose f g) r) -- | Convert from a variant where the composition of two functors have been -- mapped over the types to one where the two functors are mapped -- individually one at a time over the types. uncompose :: forall (f :: * -> *) (g :: * -> *) r. Forall r Unconstrained1 => Var (Map (Compose f g) r) -> Var (Map f (Map g r)) -- | Return a list of the labels in a row type. labels :: forall ρ c s. (IsString s, Forall ρ c) => [s] -- | An unsafe way to make a Variant. This function does not guarantee that -- the labels are all unique. unsafeMakeVar :: forall r l. KnownSymbol l => Label l -> r .! l -> Var r -- | A helper function for unsafely adding an element to the front of a -- variant. This can cause the type of the resulting variant to be -- malformed, for instance, if the variant already contains labels that -- are lexicographically before the given label. Realistically, this -- function should only be used when writing calls to metamorph. unsafeInjectFront :: forall l a r. KnownSymbol l => Var (R r) -> Var (R (l :-> a : r)) instance Data.Row.Internal.Forall r GHC.Show.Show => GHC.Show.Show (Data.Row.Variants.Var r) instance Data.Row.Internal.Forall r GHC.Classes.Eq => GHC.Classes.Eq (Data.Row.Variants.Var r) instance (Data.Row.Internal.Forall r GHC.Classes.Eq, Data.Row.Internal.Forall r GHC.Classes.Ord) => GHC.Classes.Ord (Data.Row.Variants.Var r) instance Data.Row.Internal.Forall r Control.DeepSeq.NFData => Control.DeepSeq.NFData (Data.Row.Variants.Var r) -- | This module provides the ability to discharge a polymorphic variant -- using a record that has matching fields. module Data.Row.Switch -- | A Var and a Rec can combine if their rows line up -- properly. class Switch (v :: Row *) (r :: Row *) x | v x -> r, r x -> v -- | Given a Variant and a Record of functions from each possible value of -- the variant to a single output type, apply the correct function to the -- value in the variant. switch :: Switch v r x => Var v -> Rec r -> x -- | The same as switch but with the argument order reversed caseon :: Switch v r x => Rec r -> Var v -> x instance Data.Row.Switch.Switch ('Data.Row.Internal.R '[]) ('Data.Row.Internal.R '[]) x instance (GHC.TypeLits.KnownSymbol l, Data.Row.Switch.Switch ('Data.Row.Internal.R v) ('Data.Row.Internal.R r) b) => Data.Row.Switch.Switch ('Data.Row.Internal.R ((l 'Data.Row.Internal.:-> a) : v)) ('Data.Row.Internal.R ((l 'Data.Row.Internal.:-> (a -> b)) : r)) b -- | This module includes a set of common functions for Records and -- Variants. It includes: -- -- -- -- It specifically excludes: -- -- -- -- If these particular functions are needed, they should be brought in -- qualified from one of the Data.Row.*** modules directly. module Data.Row -- | A label data Label (s :: Symbol) Label :: Label -- | This class gives the string associated with a type-level symbol. There -- are instances of the class for every concrete literal: "hello", etc. class KnownSymbol (n :: Symbol) -- | Are all of the labels in this Row unique? -- | A convenient way to provide common, easy constraints type WellBehaved ρ = (Forall ρ Unconstrained1, AllUniqueLabels ρ) -- | The variant type. data Var (r :: Row *) -- | 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 -- | Type level version of empty type Empty = R '[] -- | A lower fixity operator for type equality type a ≈ b = a ~ b -- | Alias for (r .! l) ≈ a. It is a class rather than an alias, -- so that it can be partially applied. class (r .! l ≈ a) => HasType l a r -- | Alias for .\. It is a class rather than an alias, so that it -- can be partially applied. class Lacks (l :: Symbol) (r :: Row *) -- | Does the row lack (i.e. it does not have) the specified label? -- | Type level Row append -- | Any structure over a row in which every element is similarly -- constrained can be metamorphized into another structure over the same -- row. class Forall (r :: Row k) (c :: k -> Constraint) -- | A Var and a Rec can combine if their rows line up -- properly. class Switch (v :: Row *) (r :: Row *) x | v x -> r, r x -> v -- | Given a Variant and a Record of functions from each possible value of -- the variant to a single output type, apply the correct function to the -- value in the variant. switch :: Switch v r x => Var v -> Rec r -> x -- | The same as switch but with the argument order reversed caseon :: Switch v r x => Rec r -> Var v -> x -- | The empty record empty :: Rec Empty -- | A type level way to create a singleton Row. type (l :: Symbol) .== (a :: k) = Extend l a Empty -- | The singleton record (.==) :: KnownSymbol l => Label l -> a -> Rec (l .== a) infix 7 .== -- | A pattern for the singleton record; can be used to both destruct a -- record when in a pattern position or construct one in an expression -- position. infix 7 :== -- | Turns a singleton record into a pair of the label and value. unSingleton :: forall l a. KnownSymbol l => Rec (l .== a) -> (Label l, a) -- | Type level Row element removal -- | Record restriction. Remove the label l from the record. (.-) :: KnownSymbol l => Rec r -> Label l -> Rec (r .- l) infixl 6 .- -- | Type level label fetching -- | Record selection (.!) :: KnownSymbol l => Rec r -> Label l -> r .! l -- | Record disjoint union (commutative) (.+) :: Rec l -> Rec r -> Rec (l .+ r) infixl 6 .+ -- | A type synonym for disjointness. type Disjoint l r = (WellBehaved l, WellBehaved r, Subset l (l .+ r), Subset r (l .+ r), l .+ r .\\ l ≈ r, l .+ r .\\ r ≈ l) -- | A pattern version of record union, for use in pattern matching. infixl 6 :+ -- | A pattern for variants; can be used to both destruct a variant when in -- a pattern position or construct one in an expression position. -- | Make the variant arbitrarily more diverse. diversify :: forall r' r. Var r -> Var (r .\/ r') -- | The minimum join of the two rows. -- | A Variant with no options is uninhabited. impossible :: Var Empty -> a -- | Convert a variant into either the value at the given label or a -- variant without that label. This is the basic variant destructor. trial :: KnownSymbol l => Var r -> Label l -> Either (r .! l) (Var (r .- l)) -- | A version of trial that ignores the leftover variant. trial' :: KnownSymbol l => Var r -> Label l -> Maybe (r .! l) -- | A trial over multiple types multiTrial :: forall x y. (AllUniqueLabels x, Forall (y .\\ x) Unconstrained1) => Var y -> Either (Var x) (Var (y .\\ x)) -- | Type level Row difference. That is, l .\\ r is the row -- remaining after removing any matching elements of r from -- l. -- | Return a list of the labels in a row type. labels :: forall ρ c s. (IsString s, Forall ρ c) => [s]