Data.Row.Variants

row-types-1.0.1.2: Open Records and Variants

Safe Haskell | None
Language | Haskell2010

Data.Row.Variants

Contents

- Types and constraints
- Construction
  - Extension
  - Modification
- Destruction
  - Types for destruction
- Native Conversion
- Row operations
  - Map
  - Fold
  - Applicative-like functions
  - Compose
  - labels
  - ApSingle functions
  - Coerce

Description

This module implements extensible variants using closed type families.

Synopsis

- data Label (s :: Symbol) = Label
- class KnownSymbol (n :: Symbol)
- type family AllUniqueLabels (r :: Row k) where ...
- type WellBehaved (ρ :: Row k) = (Forall ρ (Unconstrained1 :: k -> Constraint), AllUniqueLabels ρ)
- data Var (r :: Row Type)
- data Row a
- type Empty = 'R ('[] :: [LT a])
- type (≈) (a :: k) (b :: k) = a ~ b
- class (r .! l) ≈ a => HasType (l :: Symbol) (a :: k) (r :: Row k)
- pattern IsJust :: forall (l :: Symbol) r. (AllUniqueLabels r, KnownSymbol l) => Label l -> (r .! l) -> Var r
- singleton :: forall (l :: Symbol) a. KnownSymbol l => Label l -> a -> Var (l .== a)
- unSingleton :: forall (l :: Symbol) a. KnownSymbol l => Var (l .== a) -> (Label l, a)
- fromLabels :: forall c (ρ :: Row Type) f. (Alternative f, Forall ρ c, AllUniqueLabels ρ) => (forall (l :: Symbol) a. (KnownSymbol l, c a) => Label l -> f a) -> f (Var ρ)
- fromLabelsMap :: forall {a} c f g (ρ :: Row a). (Alternative f, Forall ρ c, AllUniqueLabels ρ) => (forall (l :: Symbol) (a1 :: a). (KnownSymbol l, c a1) => Label l -> f (g a1)) -> f (Var (Map g ρ))
- type family (r :: Row k) .\ (l :: Symbol) where ...
- class Lacks (l :: Symbol) (r :: Row Type)
- type family (l :: Row k) .\/ (r :: Row k) :: Row k where ...
- diversify :: forall (r' :: Row Type) (r :: Row Type). Var r -> Var (r .\/ r')
- extend :: forall a (l :: Symbol) (r :: Row Type). KnownSymbol l => Label l -> Var r -> Var (Extend l a r)
- type family (l :: Row k) .+ (r :: Row k) :: Row k where ...
- update :: forall (l :: Symbol) (r :: Row Type) a. (KnownSymbol l, (r .! l) ≈ a) => Label l -> a -> Var r -> Var r
- focus :: forall (l :: Symbol) (r :: Row Type) (r' :: Row Type) a b p f. (AllUniqueLabels r, AllUniqueLabels r', KnownSymbol l, (r .! l) ≈ a, (r' .! l) ≈ b, r' ≈ ((r .- l) .\/ (l .== b)), Applicative f, Choice p) => Label l -> p a (f b) -> p (Var r) (f (Var r'))
- type family Modify (l :: Symbol) (a :: k) (r :: Row k) :: Row k where ...
- rename :: forall (l :: Symbol) (l' :: Symbol) (r :: Row Type). (KnownSymbol l, KnownSymbol l') => Label l -> Label l' -> Var r -> Var (Rename l l' r)
- type family Rename (l :: Symbol) (l' :: Symbol) (r :: Row k) :: Row k where ...
- impossible :: Var (Empty :: Row Type) -> a
- trial :: forall (l :: Symbol) (r :: Row Type). KnownSymbol l => Var r -> Label l -> Either (Var (r .- l)) (r .! l)
- trial' :: forall (l :: Symbol) (r :: Row Type). KnownSymbol l => Var r -> Label l -> Maybe (r .! l)
- multiTrial :: forall (x :: Row Type) (y :: Row Type). (AllUniqueLabels x, FreeForall x) => Var y -> Either (Var (y .\\ x)) (Var x)
- view :: forall (l :: Symbol) (r :: Row Type). KnownSymbol l => Label l -> Var r -> Maybe (r .! l)
- type family Subset (r1 :: Row k) (r2 :: Row k) where ...
- restrict :: forall (r :: Row Type) (r' :: Row Type). (WellBehaved r, Subset r r') => Var r' -> Maybe (Var r)
- split :: forall (s :: Row Type) (r :: Row Type). (WellBehaved s, Subset s r) => Var r -> Either (Var (r .\\ s)) (Var s)
- type family (r :: Row k) .! (t :: Symbol) :: k where ...
- type family (r :: Row k) .- (s :: Symbol) :: Row k where ...
- type family (l :: Row k) .\\ (r :: Row k) :: Row k where ...
- type (.==) (l :: Symbol) (a :: k) = Extend l a (Empty :: Row k)
- toNative :: ToNative t => Var (NativeRow t) -> t
- fromNative :: FromNative t => t -> Var (NativeRow t)
- fromNativeGeneral :: forall t (ρ :: Row Type). FromNativeGeneral t ρ => t -> Var ρ
- type ToNative t = (Generic t, ToNativeG (Rep t))
- type FromNative t = (Generic t, FromNativeG (Rep t))
- type FromNativeGeneral t (ρ :: Row Type) = (Generic t, FromNativeGeneralG (Rep t) ρ)
- type family NativeRow t :: Row Type where ...
- type family Map (f :: a -> b) (r :: Row a) :: Row b where ...
- map :: forall c f (r :: Row Type). Forall r c => (forall a. c a => a -> f a) -> Var r -> Var (Map f r)
- map' :: forall f (r :: Row Type). FreeForall r => (forall a. a -> f a) -> Var r -> Var (Map f r)
- transform :: forall {a} c (r :: Row a) f g. Forall r c => (forall (a1 :: a). c a1 => f a1 -> g a1) -> Var (Map f r) -> Var (Map g r)
- transform' :: forall {a} (r :: Row a) f g. FreeForall r => (forall (a1 :: a). f a1 -> g a1) -> Var (Map f r) -> Var (Map g r)
- class Forall (r :: Row k) (c :: k -> Constraint)
- erase :: forall c (ρ :: Row Type) b. Forall ρ c => (forall a. c a => a -> b) -> Var ρ -> b
- eraseWithLabels :: forall c (ρ :: Row Type) s b. (Forall ρ c, IsString s) => (forall a. c a => a -> b) -> Var ρ -> (s, b)
- eraseZipGeneral :: forall c (ρ :: Row Type) b s. (Forall ρ c, IsString s) => (forall x y. (c x, c y) => Either (s, x, x) ((s, x), (s, y)) -> b) -> Var ρ -> Var ρ -> b
- eraseZip :: forall c (ρ :: Row Type) b. Forall ρ c => (forall a. c a => a -> a -> b) -> Var ρ -> Var ρ -> Maybe b
- traverse :: forall c f (r :: Row Type). (Forall r c, Functor f) => (forall a. c a => a -> f a) -> Var r -> f (Var r)
- traverseMap :: forall {a} c f g h (r :: Row a). (Forall r c, Functor f) => (forall (a1 :: a). c a1 => g a1 -> f (h a1)) -> Var (Map g r) -> f (Var (Map h r))
- sequence :: forall f (r :: Row Type). (FreeForall r, Functor f) => Var (Map f r) -> f (Var r)
- compose :: forall {k} {a} (f :: k -> Type) (g :: a -> k) (r :: Row a). FreeForall r => Var (Map f (Map g r)) -> Var (Map (Compose f g) r)
- uncompose :: forall {b} {a} (f :: b -> Type) (g :: a -> b) (r :: Row a). FreeForall r => Var (Map (Compose f g) r) -> Var (Map f (Map g r))
- labels :: forall {k} (ρ :: Row k) (c :: k -> Constraint) s. (IsString s, Forall ρ c) => [s]
- eraseSingle :: forall {a} c (fs :: Row (a -> Type)) (x :: a) y. Forall fs c => (forall (f :: a -> Type). c f => f x -> y) -> Var (ApSingle fs x) -> y
- mapSingle :: forall {a} c (fs :: Row (a -> Type)) (x :: a) (y :: a). Forall fs c => (forall (f :: a -> Type). c f => f x -> f y) -> Var (ApSingle fs x) -> Var (ApSingle fs y)
- mapSingleA :: forall {a} c (fs :: Row (a -> Type)) g (x :: a) (y :: a). (Forall fs c, Functor g) => (forall (f :: a -> Type). c f => f x -> g (f y)) -> Var (ApSingle fs x) -> g (Var (ApSingle fs y))
- eraseZipSingle :: forall {a} c (fs :: Row (a -> Type)) (x :: a) (y :: a) z. Forall fs c => (forall (f :: a -> Type). c f => f x -> f y -> z) -> Var (ApSingle fs x) -> Var (ApSingle fs y) -> Maybe z
- coerceVar :: forall (r1 :: Row Type) (r2 :: Row Type). BiForall r1 r2 (Coercible :: Type -> Type -> Constraint) => Var r1 -> Var r2

# Types and constraints

data Label (s :: Symbol) #

A label

Constructors

Label |

#### Instances

Instances details

x ≈ y => IsLabel x (Label y) # |
Instance details Defined in Data.Row.Internal Methods fromLabel :: Label y #
KnownSymbol s => Show (Label s) # |
Instance details Defined in Data.Row.Internal Methods showsPrec :: Int -> Label s -> ShowS # show :: Label s -> String # showList :: [Label s] -> ShowS #
Eq (Label s) # |
Instance details Defined in Data.Row.Internal Methods (==) :: Label s -> Label s -> Bool # (/=) :: Label s -> Label s -> Bool #

class KnownSymbol (n :: Symbol) #

This class gives the string associated with a type-level symbol. There are instances of the class for every concrete literal: "hello", etc.

@since base-4.7.0.0

Minimal complete definition

symbolSing

type family AllUniqueLabels (r :: Row k) where ... #

Are all of the labels in this Row unique?

Equations

AllUniqueLabels ('R r :: Row k) = AllUniqueLabelsR r |

type WellBehaved (ρ :: Row k) = (Forall ρ (Unconstrained1 :: k -> Constraint), AllUniqueLabels ρ) #

A convenient way to provide common, easy constraints

data Var (r :: Row Type) #

The variant type.

#### Instances

Instances details

(AllUniqueLabels r, KnownSymbol name, (r .! name) ≈ a, r ≈ ((r .- name) .\/ (name .== a))) => AsConstructor' name (Var r) a # |
Instance details Defined in Data.Row.Variants Methods _Ctor' :: Prism (Var r) (Var r) a a #
(AllUniqueLabels r, AllUniqueLabels r', KnownSymbol name, (r .! name) ≈ a, (r' .! name) ≈ b, r' ≈ ((r .- name) .\/ (name .== b))) => AsConstructor name (Var r) (Var r') a b # | Every possibility of a row-types based variant has an `AsConstructor` instance.
Instance details Defined in Data.Row.Variants Methods _Ctor :: Prism (Var r) (Var r') a b #
Forall r NFData => NFData (Var r) # |
Instance details Defined in Data.Row.Variants Methods rnf :: Var r -> () #
GenericVar r => Generic (Var r) # |
Instance details Defined in Data.Row.Variants Associated Types
type Rep (Var r) |
Instance details Defined in Data.Row.Variants type Rep (Var r)
Methods from :: Var r -> Rep (Var r) x # to :: Rep (Var r) x -> Var r #
Forall r Show => Show (Var r) # |
Instance details Defined in Data.Row.Variants Methods showsPrec :: Int -> Var r -> ShowS # show :: Var r -> String # showList :: [Var r] -> ShowS #
Forall r Eq => Eq (Var r) # |
Instance details Defined in Data.Row.Variants Methods (==) :: Var r -> Var r -> Bool # (/=) :: Var r -> Var r -> Bool #
(Forall r Eq, Forall r Ord) => Ord (Var r) # |
Instance details Defined in Data.Row.Variants Methods compare :: Var r -> Var r -> Ordering # (<) :: Var r -> Var r -> Bool # (<=) :: Var r -> Var r -> Bool # (>) :: Var r -> Var r -> Bool # (>=) :: Var r -> Var r -> Bool # max :: Var r -> Var r -> Var r # min :: Var r -> Var r -> Var r #
type Rep (Var r) # |
Instance details Defined in Data.Row.Variants type Rep (Var r)

data Row a #

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.

type Empty = 'R ('[] :: [LT a]) #

Type level version of `empty`

type (≈) (a :: k) (b :: k) = a ~ b infix 4 #

A lower fixity operator for type equality

# Construction

class (r .! l) ≈ a => HasType (l :: Symbol) (a :: k) (r :: Row k) #

Alias for `(r .! l) ≈ a`. It is a class rather than an alias, so that it can be partially applied.

#### Instances

Instances details

(r .! l) ≈ a => HasType l (a :: k) (r :: Row k) # |
Instance details Defined in Data.Row.Internal

pattern IsJust :: forall (l :: Symbol) r. (AllUniqueLabels r, KnownSymbol l) => Label l -> (r .! l) -> Var 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.

singleton :: forall (l :: Symbol) a. KnownSymbol l => Label l -> a -> Var (l .== a) #

A quick constructor to create a singleton variant.

unSingleton :: forall (l :: Symbol) a. KnownSymbol l => Var (l .== a) -> (Label l, a) #

A quick destructor for singleton variants.

fromLabels :: forall c (ρ :: Row Type) f. (Alternative f, Forall ρ c, AllUniqueLabels ρ) => (forall (l :: Symbol) a. (KnownSymbol l, c a) => Label l -> f a) -> f (Var ρ) #

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.

fromLabelsMap :: forall {a} c f g (ρ :: Row a). (Alternative f, Forall ρ c, AllUniqueLabels ρ) => (forall (l :: Symbol) (a1 :: a). (KnownSymbol l, c a1) => Label l -> f (g a1)) -> f (Var (Map g ρ)) #

Initialize a variant over a `Map`.

## Extension

type family (r :: Row k) .\ (l :: Symbol) where ... infixl 4 #

Does the row lack (i.e. it does not have) the specified label?

Equations

('R ('[] :: [LT k]) :: Row k) .\ l = Unconstrained |
('R r :: Row k) .\ l = LacksR l r r |

class Lacks (l :: Symbol) (r :: Row Type) #

Alias for `.\`. It is a class rather than an alias, so that it can be partially applied.

#### Instances

Instances details

r .\ l => Lacks l r # |
Instance details Defined in Data.Row.Internal

type family (l :: Row k) .\/ (r :: Row k) :: Row k where ... infixl 6 #

The minimum join of the two rows.

Equations

(x :: Row k) .\/ ('R ('[] :: [LT k]) :: Row k) = x |
('R ('[] :: [LT k]) :: Row k) .\/ (y :: Row k) = y |
('R l :: Row a) .\/ ('R r :: Row a) = 'R (MinJoinR l r) |

diversify :: forall (r' :: Row Type) (r :: Row Type). Var r -> Var (r .\/ r') #

Make the variant arbitrarily more diverse.

extend :: forall a (l :: Symbol) (r :: Row Type). KnownSymbol l => Label l -> Var r -> Var (Extend l a r) #

A weaker version of `diversify`, but it's helpful for `metamorph` as it explicitly uses `Extend`.

type family (l :: Row k) .+ (r :: Row k) :: Row k where ... infixl 6 #

Type level Row append

Equations

(x :: Row k) .+ ('R ('[] :: [LT k]) :: Row k) = x |
('R ('[] :: [LT k]) :: Row k) .+ (y :: Row k) = y |
(x :: Row k) .+ ('R '[l ':-> a] :: Row k) = Extend l a x |
('R '[l ':-> a] :: Row k) .+ (y :: Row k) = Extend l a y |
('R l :: Row a) .+ ('R r :: Row a) = 'R (Merge l r) |

## Modification

update :: forall (l :: Symbol) (r :: Row Type) a. (KnownSymbol l, (r .! l) ≈ a) => Label l -> a -> Var r -> Var r #

If the variant exists at the given label, update it to the given value. Otherwise, do nothing.

focus :: forall (l :: Symbol) (r :: Row Type) (r' :: Row Type) a b p f. (AllUniqueLabels r, AllUniqueLabels r', KnownSymbol l, (r .! l) ≈ a, (r' .! l) ≈ b, r' ≈ ((r .- l) .\/ (l .== b)), Applicative f, Choice p) => Label l -> p a (f b) -> p (Var r) (f (Var r')) #

If the variant exists at the given label, focus on the value associated with it. Otherwise, do nothing.

type family Modify (l :: Symbol) (a :: k) (r :: Row k) :: Row k where ... #

Type level Row modification

Equations

Modify l (a2 :: a1) ('R ρ :: Row a1) = 'R (ModifyR l a2 ρ) |

rename :: forall (l :: Symbol) (l' :: Symbol) (r :: Row Type). (KnownSymbol l, KnownSymbol l') => Label l -> Label l' -> Var r -> Var (Rename l l' r) #

Rename the given label.

type family Rename (l :: Symbol) (l' :: Symbol) (r :: Row k) :: Row k where ... #

Type level row renaming

Equations

Rename l l' (r :: Row k) = Extend l' (r .! l) (r .- l) |

# Destruction

impossible :: Var (Empty :: Row Type) -> a #

A Variant with no options is uninhabited.

trial :: forall (l :: Symbol) (r :: Row Type). KnownSymbol l => Var r -> Label l -> Either (Var (r .- l)) (r .! l) #

Convert a variant into either the value at the given label or a variant without that label. This is the basic variant destructor.

trial' :: forall (l :: Symbol) (r :: Row Type). KnownSymbol l => Var r -> Label l -> Maybe (r .! l) #

A version of `trial` that ignores the leftover variant.

multiTrial :: forall (x :: Row Type) (y :: Row Type). (AllUniqueLabels x, FreeForall x) => Var y -> Either (Var (y .\\ x)) (Var x) #

A trial over multiple types

view :: forall (l :: Symbol) (r :: Row Type). KnownSymbol l => Label l -> Var r -> Maybe (r .! l) #

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

type family Subset (r1 :: Row k) (r2 :: Row k) where ... #

Is the first row a subset of the second? Or, does the second row contain every binding that the first one does?

Equations

Subset ('R ('[] :: [LT k]) :: Row k) (r :: Row k) = Unconstrained |
Subset ('R ((l ':-> a) ': x) :: Row k) (r :: Row k) = ((r .! l) ≈ a, Subset ('R x) r) |

restrict :: forall (r :: Row Type) (r' :: Row Type). (WellBehaved r, Subset r r') => Var r' -> Maybe (Var r) #

Arbitrary variant restriction. Turn a variant into a subset of itself.

split :: forall (s :: Row Type) (r :: Row Type). (WellBehaved s, Subset s r) => Var r -> Either (Var (r .\\ s)) (Var s) #

Split a variant into two sub-variants.

## Types for destruction

type family (r :: Row k) .! (t :: Symbol) :: k where ... infixl 5 #

Type level label fetching

Equations

('R r :: Row k) .! l = Get l r |

type family (r :: Row k) .- (s :: Symbol) :: Row k where ... infixl 6 #

Type level Row element removal

Equations

('R r :: Row a) .- l = 'R (Remove l r) |

type family (l :: Row k) .\\ (r :: Row k) :: Row k where ... infixl 6 #

Type level Row difference. That is, `l `.\\` r` is the row remaining after removing any matching elements of `r` from `l`.

Equations

('R l :: Row a) .\\ ('R r :: Row a) = 'R (Diff l r) |

type (.==) (l :: Symbol) (a :: k) = Extend l a (Empty :: Row k) infix 7 #

A type level way to create a singleton Row.

# Native Conversion

The `toNative` and `fromNative` functions allow one to convert between `Var`s and regular Haskell data types ("native" types) that have the same number of constructors such that each constructor has one field and the same name as one of the options of the `Var`, which has the same type as that field. As expected, they compose to form the identity. Alternatively, one may use `fromNativeGeneral`, which allows a variant with excess options to still be transformed to a native type. Because of this, `fromNativeGeneral` requires a type application (although `fromNative` does not). The only requirement is that the native Haskell data type be an instance of `Generic`.

For example, consider the following simple data type:

    >>> data Pet = Dog {age :: Int} | Cat {age :: Int} deriving (Generic, Show)

Then, we have the following:

    >>> toNative $ IsJust (Label @"Dog") 3 :: Pet
    Dog {age = 3}
    >>> V.fromNative $ Dog 3 :: Var ("Dog" .== Int .+ "Cat" .== Int)
    {Dog=3}

toNative :: ToNative t => Var (NativeRow t) -> t #

Convert a variant to a native Haskell type.

fromNative :: FromNative t => t -> Var (NativeRow t) #

Convert a Haskell variant to a row-types Var.

fromNativeGeneral :: forall t (ρ :: Row Type). FromNativeGeneral t ρ => t -> Var ρ #

Convert a Haskell variant to a row-types Var.

type ToNative t = (Generic t, ToNativeG (Rep t)) #

type FromNative t = (Generic t, FromNativeG (Rep t)) #

type FromNativeGeneral t (ρ :: Row Type) = (Generic t, FromNativeGeneralG (Rep t) ρ) #

type family NativeRow t :: Row Type where ... #

Equations

NativeRow t = NativeRowG (Rep t) |

# Row operations

## Map

type family Map (f :: a -> b) (r :: Row a) :: Row b where ... #

Map a type level function over a Row.

Equations

Map (f :: a1 -> a2) ('R r :: Row a1) = 'R (MapR f r) |

map :: forall c f (r :: Row Type). Forall r c => (forall a. c a => a -> f a) -> Var r -> Var (Map f r) #

A function to map over a variant given a constraint.

map' :: forall f (r :: Row Type). FreeForall r => (forall a. a -> f a) -> Var r -> Var (Map f r) #

A function to map over a variant given no constraint.

transform :: forall {a} c (r :: Row a) f g. Forall r c => (forall (a1 :: a). c a1 => f a1 -> g a1) -> Var (Map f r) -> Var (Map g 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 {a} (r :: Row a) f g. FreeForall r => (forall (a1 :: a). f a1 -> g a1) -> Var (Map f r) -> Var (Map g r) #

A form of `transformC` that doesn't have a constraint on `a`

## Fold

class Forall (r :: Row k) (c :: k -> Constraint) #

Any structure over a row in which every element is similarly constrained can be metamorphized into another structure over the same row.

Minimal complete definition

metamorph

#### Instances

Instances details

(KnownSymbol ℓ, c τ, Forall ('R ρ) c, FrontExtends ℓ τ ('R ρ), AllUniqueLabels (Extend ℓ τ ('R ρ))) => Forall ('R ((ℓ ':-> τ) ': ρ) :: Row k) (c :: k -> Constraint) # |
Instance details Defined in Data.Row.Internal Methods metamorph :: forall p f g h. Bifunctor p => Proxy (Proxy h, Proxy p) -> (f (Empty :: Row k) -> g (Empty :: Row k)) -> (forall (ℓ0 :: Symbol) (τ0 :: k) (ρ0 :: Row k). (KnownSymbol ℓ0, c τ0, HasType ℓ0 τ0 ρ0) => Label ℓ0 -> f ρ0 -> p (f (ρ0 .- ℓ0)) (h τ0)) -> (forall (ℓ1 :: Symbol) (τ1 :: k) (ρ1 :: Row k). (KnownSymbol ℓ1, c τ1, FrontExtends ℓ1 τ1 ρ1, AllUniqueLabels (Extend ℓ1 τ1 ρ1)) => Label ℓ1 -> p (g ρ1) (h τ1) -> g (Extend ℓ1 τ1 ρ1)) -> f ('R ((ℓ ':-> τ) ': ρ)) -> g ('R ((ℓ ':-> τ) ': ρ)) #
Forall ('R ('[] :: [LT k]) :: Row k) (c :: k -> Constraint) # |
Instance details Defined in Data.Row.Internal Methods metamorph :: forall p f g h. Bifunctor p => Proxy (Proxy h, Proxy p) -> (f (Empty :: Row k) -> g (Empty :: Row k)) -> (forall (ℓ :: Symbol) (τ :: k) (ρ :: Row k). (KnownSymbol ℓ, c τ, HasType ℓ τ ρ) => Label ℓ -> f ρ -> p (f (ρ .- ℓ)) (h τ)) -> (forall (ℓ :: Symbol) (τ :: k) (ρ :: Row k). (KnownSymbol ℓ, c τ, FrontExtends ℓ τ ρ, AllUniqueLabels (Extend ℓ τ ρ)) => Label ℓ -> p (g ρ) (h τ) -> g (Extend ℓ τ ρ)) -> f ('R ('[] :: [LT k])) -> g ('R ('[] :: [LT k])) #

erase :: forall c (ρ :: Row Type) b. Forall ρ c => (forall a. c a => a -> b) -> Var ρ -> b #

A standard fold

eraseWithLabels :: forall c (ρ :: Row Type) s b. (Forall ρ c, IsString s) => (forall a. c a => a -> b) -> Var ρ -> (s, b) #

A fold with labels

eraseZipGeneral :: forall c (ρ :: Row Type) b s. (Forall ρ c, IsString s) => (forall x y. (c x, c y) => Either (s, x, x) ((s, x), (s, y)) -> b) -> Var ρ -> Var ρ -> b #

A fold over two variants at once. A call `eraseZipGeneral f x y` will return `f (Left (show l, a, b))` when `x` and `y` both have values at the same label `l` and will return `f (Right ((show l1, a), (show l2, b)))` when they have values at different labels `l1` and `l2` respectively.

eraseZip :: forall c (ρ :: Row Type) b. Forall ρ c => (forall a. c a => a -> a -> b) -> Var ρ -> Var ρ -> Maybe b #

A simpler fold over two variants at once

## Applicative-like functions

traverse :: forall c f (r :: Row Type). (Forall r c, Functor f) => (forall a. c a => a -> f a) -> Var r -> f (Var r) #

Traverse a function over a variant.

traverseMap :: forall {a} c f g h (r :: Row a). (Forall r c, Functor f) => (forall (a1 :: a). c a1 => g a1 -> f (h a1)) -> Var (Map g r) -> f (Var (Map h r)) #

Traverse a function over a Mapped variant.

sequence :: forall f (r :: Row Type). (FreeForall r, Functor f) => Var (Map f r) -> f (Var r) #

Applicative sequencing over a variant

## Compose

We can easily convert between mapping two functors over the types of a row and mapping the composition of the two functors. The following two functions perform this composition with the gaurantee that:

    >>> compose . uncompose = id

    >>> uncompose . compose = id

compose :: forall {k} {a} (f :: k -> Type) (g :: a -> k) (r :: Row a). FreeForall r => Var (Map f (Map g r)) -> Var (Map (Compose f g) 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.

uncompose :: forall {b} {a} (f :: b -> Type) (g :: a -> b) (r :: Row a). FreeForall r => Var (Map (Compose f g) r) -> Var (Map f (Map 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.

## labels

labels :: forall {k} (ρ :: Row k) (c :: k -> Constraint) s. (IsString s, Forall ρ c) => [s] #

Return a list of the labels in a row type.

## ApSingle functions

eraseSingle :: forall {a} c (fs :: Row (a -> Type)) (x :: a) y. Forall fs c => (forall (f :: a -> Type). c f => f x -> y) -> Var (ApSingle fs x) -> y #

A version of `erase` that works even when the row-type of the variant argument is of the form `ApSingle fs x`.

mapSingle :: forall {a} c (fs :: Row (a -> Type)) (x :: a) (y :: a). Forall fs c => (forall (f :: a -> Type). c f => f x -> f y) -> Var (ApSingle fs x) -> Var (ApSingle fs y) #

Performs a functorial-like map over an `ApSingle` variant. In other words, it acts as a variant transformer to convert a variant of `f x` values to a variant of `f y` values. If no constraint is needed, instantiate the first type argument with `Unconstrained1`.

mapSingleA :: forall {a} c (fs :: Row (a -> Type)) g (x :: a) (y :: a). (Forall fs c, Functor g) => (forall (f :: a -> Type). c f => f x -> g (f y)) -> Var (ApSingle fs x) -> g (Var (ApSingle fs y)) #

Like `mapSingle`, but works over a functor.

eraseZipSingle :: forall {a} c (fs :: Row (a -> Type)) (x :: a) (y :: a) z. Forall fs c => (forall (f :: a -> Type). c f => f x -> f y -> z) -> Var (ApSingle fs x) -> Var (ApSingle fs y) -> Maybe z #

A version of `eraseZip` that works even when the row-types of the variant arguments are of the form `ApSingle fs x`.

## Coerce

coerceVar :: forall (r1 :: Row Type) (r2 :: Row Type). BiForall r1 r2 (Coercible :: Type -> Type -> Constraint) => Var r1 -> Var r2 #

Coerce a variant to a coercible representation. The `BiForall` in the context indicates that the type of any option in `r1` can be coerced to the type of the corresponding option in `r2`.

Internally, this is implemented just with `unsafeCoerce`, but we provide the following implementation as a proof:

    newtype ConstV a b = ConstV { unConstV :: Var a }
    newtype ConstV a b = FlipConstV { unFlipConstV :: Var b }
    coerceVar :: forall r1 r2. BiForall r1 r2 Coercible => Var r1 -> Var r2
    coerceVar = unFlipConstV . biMetamorph @_ @_ @r1 @r2 @Coercible @Either @ConstV @FlipConstV @Const Proxy doNil doUncons doCons . ConstV
      where
        doNil = impossible . unConstV
        doUncons l = bimap ConstV Const . flip trial l . unConstV
        doCons :: forall ℓ τ1 τ2 ρ1 ρ2. (KnownSymbol ℓ, Coercible τ1 τ2, AllUniqueLabels (Extend ℓ τ2 ρ2))
               => Label ℓ -> Either (FlipConstV ρ1 ρ2) (Const τ1 τ2)
               -> FlipConstV (Extend ℓ τ1 ρ1) (Extend ℓ τ2 ρ2)
        doCons l (Left (FlipConstV v)) = FlipConstV $ extend @τ2 l v
        doCons l (Right (Const x)) = FlipConstV $ IsJust l (coerce @τ1 @τ2 x)
          \\ extendHas @ρ2 @ℓ @τ2