data-diverse-3.0.0.0: Extensible records and polymorphic variants.

Safe HaskellNone
LanguageHaskell2010

Data.Diverse.Many

Contents

Description

Re-export Many without the constructor

Synopsis

Many type

data Many (xs :: [Type]) Source #

A Many is an anonymous product type (also know as polymorphic record), with no limit on the number of fields.

The following functions are available can be used to manipulate unique fields

These functions are type specified. This means labels are not required because the types themselves can be used to access the 'Many. It is a compile error to use those functions for duplicate fields.

For duplicate fields, Nat-indexed versions of the functions are available:

Encoding: The record is encoded as (S.Seq Any). This encoding should reasonabily efficient for any number of fields.

The map Key is index + offset of the type in the typelist. The Offset is used to allow efficient cons prefix.

Key = Index of type in typelist + Offset

The constructor will guarantee the correct number and types of the elements. The constructor is only exported in the Data.Diverse.Many.Internal module

Instances

AFunctor Many_ c as => AFunctor Many c as Source #

Given a Case that transforms each type in the typelist, convert a Many xs to Many (CaseResults c xs)

Methods

afmap :: c as -> Many as -> Many (CaseResults * * c as) Source #

Eq (Many_ xs) => Eq (Many xs) Source #

Two Manys are equal if all their fields equal

Methods

(==) :: Many xs -> Many xs -> Bool #

(/=) :: Many xs -> Many xs -> Bool #

Ord (Many_ xs) => Ord (Many xs) Source #

Two Manys are ordered by compareing their fields in index order

Methods

compare :: Many xs -> Many xs -> Ordering #

(<) :: Many xs -> Many xs -> Bool #

(<=) :: Many xs -> Many xs -> Bool #

(>) :: Many xs -> Many xs -> Bool #

(>=) :: Many xs -> Many xs -> Bool #

max :: Many xs -> Many xs -> Many xs #

min :: Many xs -> Many xs -> Many xs #

Read (Many_ xs) => Read (Many xs) Source #
read "5 . False . X . Just O . nil" == (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil
Show (Many_ xs) => Show (Many xs) Source #
show (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil == "5 . False . X . Just O . nil" ==

Methods

showsPrec :: Int -> Many xs -> ShowS #

show :: Many xs -> String #

showList :: [Many xs] -> ShowS #

Generic (Many ((:) Type x xs)) Source #

A Generic instance encoded as the front value :*: with the aft Many. The C1 and S1 metadata are not encoded.

Associated Types

type Rep (Many ((Type ': x) xs)) :: * -> * #

Methods

from :: Many ((Type ': x) xs) -> Rep (Many ((Type ': x) xs)) x #

to :: Rep (Many ((Type ': x) xs)) x -> Many ((Type ': x) xs) #

Generic (Many ([] Type)) Source #

A terminating Generic instance encoded as a nil.

Associated Types

type Rep (Many [Type]) :: * -> * #

Methods

from :: Many [Type] -> Rep (Many [Type]) x #

to :: Rep (Many [Type]) x -> Many [Type] #

Semigroup (Many_ xs) => Semigroup (Many xs) Source # 

Methods

(<>) :: Many xs -> Many xs -> Many xs #

sconcat :: NonEmpty (Many xs) -> Many xs #

stimes :: Integral b => b -> Many xs -> Many xs #

Monoid (Many_ xs) => Monoid (Many xs) Source # 

Methods

mempty :: Many xs #

mappend :: Many xs -> Many xs -> Many xs #

mconcat :: [Many xs] -> Many xs #

(NFData x, NFData (Many xs)) => NFData (Many ((:) * x xs)) Source # 

Methods

rnf :: Many ((* ': x) xs) -> () #

NFData (Many ([] Type)) Source # 

Methods

rnf :: Many [Type] -> () #

type Rep (Many ((:) Type x xs)) Source # 
type Rep (Many ((:) Type x xs)) = (:*:) * (Rec0 * x) (Rec0 * (Many xs))
type Rep (Many ([] Type)) Source # 
type Rep (Many ([] Type)) = U1 *

Isomorphism

class IsMany t xs a where Source #

This instance allows converting to and from Many There are instances for converting tuples of up to size 15.

Minimal complete definition

toMany, fromMany

Methods

toMany :: t xs a -> Many xs Source #

fromMany :: Many xs -> t xs a Source #

Instances

IsMany * (Tagged [Type]) ([] Type) () Source #

These instances add about 7 seconds to the compile time!

Methods

toMany :: [Type] () a -> Many () Source #

fromMany :: Many () -> [Type] () a Source #

IsMany * (Tagged [Type]) ((:) Type a ([] Type)) a Source #

This single field instance is the reason for Tagged wrapper. Otherwise this instance will overlap.

Methods

toMany :: (Type ': a) [Type] a a -> Many a Source #

fromMany :: Many a -> (Type ': a) [Type] a a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ([] Type))) (a, b) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) [Type]) (a, b) a -> Many (a, b) Source #

fromMany :: Many (a, b) -> (Type ': a) ((Type ': b) [Type]) (a, b) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ([] Type)))) (a, b, c) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) [Type])) (a, b, c) a -> Many (a, b, c) Source #

fromMany :: Many (a, b, c) -> (Type ': a) ((Type ': b) ((Type ': c) [Type])) (a, b, c) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ([] Type))))) (a, b, c, d) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) [Type]))) (a, b, c, d) a -> Many (a, b, c, d) Source #

fromMany :: Many (a, b, c, d) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) [Type]))) (a, b, c, d) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ((:) Type e ([] Type)))))) (a, b, c, d, e) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) [Type])))) (a, b, c, d, e) a -> Many (a, b, c, d, e) Source #

fromMany :: Many (a, b, c, d, e) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) [Type])))) (a, b, c, d, e) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ((:) Type e ((:) Type f ([] Type))))))) (a, b, c, d, e, f) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) [Type]))))) (a, b, c, d, e, f) a -> Many (a, b, c, d, e, f) Source #

fromMany :: Many (a, b, c, d, e, f) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) [Type]))))) (a, b, c, d, e, f) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ((:) Type e ((:) Type f ((:) Type g ([] Type)))))))) (a, b, c, d, e, f, g) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) [Type])))))) (a, b, c, d, e, f, g) a -> Many (a, b, c, d, e, f, g) Source #

fromMany :: Many (a, b, c, d, e, f, g) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) [Type])))))) (a, b, c, d, e, f, g) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ((:) Type e ((:) Type f ((:) Type g ((:) Type h ([] Type))))))))) (a, b, c, d, e, f, g, h) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) [Type]))))))) (a, b, c, d, e, f, g, h) a -> Many (a, b, c, d, e, f, g, h) Source #

fromMany :: Many (a, b, c, d, e, f, g, h) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) [Type]))))))) (a, b, c, d, e, f, g, h) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ((:) Type e ((:) Type f ((:) Type g ((:) Type h ((:) Type i ([] Type)))))))))) (a, b, c, d, e, f, g, h, i) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) [Type])))))))) (a, b, c, d, e, f, g, h, i) a -> Many (a, b, c, d, e, f, g, h, i) Source #

fromMany :: Many (a, b, c, d, e, f, g, h, i) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) [Type])))))))) (a, b, c, d, e, f, g, h, i) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ((:) Type e ((:) Type f ((:) Type g ((:) Type h ((:) Type i ((:) Type j ([] Type))))))))))) (a, b, c, d, e, f, g, h, i, j) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) [Type]))))))))) (a, b, c, d, e, f, g, h, i, j) a -> Many (a, b, c, d, e, f, g, h, i, j) Source #

fromMany :: Many (a, b, c, d, e, f, g, h, i, j) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) [Type]))))))))) (a, b, c, d, e, f, g, h, i, j) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ((:) Type e ((:) Type f ((:) Type g ((:) Type h ((:) Type i ((:) Type j ((:) Type k ([] Type)))))))))))) (a, b, c, d, e, f, g, h, i, j, k) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) ((Type ': k) [Type])))))))))) (a, b, c, d, e, f, g, h, i, j, k) a -> Many (a, b, c, d, e, f, g, h, i, j, k) Source #

fromMany :: Many (a, b, c, d, e, f, g, h, i, j, k) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) ((Type ': k) [Type])))))))))) (a, b, c, d, e, f, g, h, i, j, k) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ((:) Type e ((:) Type f ((:) Type g ((:) Type h ((:) Type i ((:) Type j ((:) Type k ((:) Type l ([] Type))))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) ((Type ': k) ((Type ': l) [Type]))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l) a -> Many (a, b, c, d, e, f, g, h, i, j, k, l) Source #

fromMany :: Many (a, b, c, d, e, f, g, h, i, j, k, l) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) ((Type ': k) ((Type ': l) [Type]))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ((:) Type e ((:) Type f ((:) Type g ((:) Type h ((:) Type i ((:) Type j ((:) Type k ((:) Type l ((:) Type m ([] Type)))))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l, m) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) ((Type ': k) ((Type ': l) ((Type ': m) [Type])))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l, m) a -> Many (a, b, c, d, e, f, g, h, i, j, k, l, m) Source #

fromMany :: Many (a, b, c, d, e, f, g, h, i, j, k, l, m) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) ((Type ': k) ((Type ': l) ((Type ': m) [Type])))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l, m) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ((:) Type e ((:) Type f ((:) Type g ((:) Type h ((:) Type i ((:) Type j ((:) Type k ((:) Type l ((:) Type m ((:) Type n ([] Type))))))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l, m, n) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) ((Type ': k) ((Type ': l) ((Type ': m) ((Type ': n) [Type]))))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l, m, n) a -> Many (a, b, c, d, e, f, g, h, i, j, k, l, m, n) Source #

fromMany :: Many (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) ((Type ': k) ((Type ': l) ((Type ': m) ((Type ': n) [Type]))))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l, m, n) a Source #

IsMany * (Tagged [Type]) ((:) Type a ((:) Type b ((:) Type c ((:) Type d ((:) Type e ((:) Type f ((:) Type g ((:) Type h ((:) Type i ((:) Type j ((:) Type k ((:) Type l ((:) Type m ((:) Type n ((:) Type o ([] Type)))))))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) Source # 

Methods

toMany :: (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) ((Type ': k) ((Type ': l) ((Type ': m) ((Type ': n) ((Type ': o) [Type])))))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) a -> Many (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) Source #

fromMany :: Many (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> (Type ': a) ((Type ': b) ((Type ': c) ((Type ': d) ((Type ': e) ((Type ': f) ((Type ': g) ((Type ': h) ((Type ': i) ((Type ': j) ((Type ': k) ((Type ': l) ((Type ': m) ((Type ': n) ((Type ': o) [Type])))))))))))))) (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) a Source #

fromMany' :: IsMany Tagged xs a => Many xs -> a Source #

Converts from a Many to a value (eg a tuple), via a Tagged wrapper

toMany' :: IsMany Tagged xs a => a -> Many xs Source #

Converts from a value (eg a tuple) to a Many, via a Tagged wrapper

Construction

nil :: Many '[] Source #

Empty Many.

single :: x -> Many '[x] Source #

Create a Many from a single value. Analogous to singleton

prefix :: x -> Many xs -> Many (x ': xs) infixr 5 Source #

Add an element to the left of a Many. Not named cons to avoid conflict with cons

(./) :: x -> Many xs -> Many (x ': xs) infixr 5 Source #

Infix version of prefix.

Mnemonic: Element on the left is smaller ./ than the larger Many to the right.

postfix :: Many xs -> y -> Many (Append xs '[y]) infixl 5 Source #

Add an element to the right of a Many Not named snoc to avoid conflict with snoc

postfix' :: forall y xs. MaybeUniqueMember y xs => Many xs -> y -> Many (SnocUnique xs y) infixl 5 Source #

Add an element to the right of a Many iff the field doesn't already exist.

(\.) :: Many xs -> y -> Many (Append xs '[y]) infixl 5 Source #

Infix version of postfix.

Mnemonic: Many is larger \. than the smaller element

append :: Many xs -> Many ys -> Many (Append xs ys) infixr 5 Source #

Appends two Manys together

(/./) :: Many xs -> Many ys -> Many (Append xs ys) infixr 5 Source #

Infix version of append.

Mnemonic: prefix ./ with an extra slash (meaning Many) in front.

Simple queries

viewf :: Many (x ': xs) -> (x, Many xs) Source #

Split a non-empty Many into the first element, then the rest of the Many. Analogous to viewl

viewb :: Many (x ': xs) -> (Many (Init (x ': xs)), Last (x ': xs)) Source #

Split a non-empty Many into initial part of Many, and the last element. Analogous to viewr

front :: Many (x ': xs) -> x Source #

Extract the first element of a Many, which guaranteed to be non-empty. Analogous to head

back :: Many (x ': xs) -> Last (x ': xs) Source #

Extract the back element of a Many, which guaranteed to be non-empty. Analogous to last

aft :: Many (x ': xs) -> Many xs Source #

Extract the elements after the front of a Many, which guaranteed to be non-empty. Analogous to tail

fore :: Many (x ': xs) -> Many (Init (x ': xs)) Source #

Return all the elements of a Many except the back one, which guaranteed to be non-empty. Analogous to init

Single field

Getter for single field

grab :: forall x xs. UniqueMember x xs => Many xs -> x Source #

Getter by unique type. Get the field with type x.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil
grab @Int x `shouldBe` 5

grabL :: forall l x xs. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => Many xs -> x Source #

Getter by label. Get the value of the field with tag label which can be any type not just KnownSymbol.

let y = False ./ Tagged @Foo 'X' ./ Tagged @Hi True ./ nil
grabL @Foo y `shouldBe` Tagged @Foo 'X'
grabL @Hi y `shouldBe` Tagged @Hi True

grabTag :: forall l x xs. (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs) => Many xs -> x Source #

Variation of grabL specialized for Tagged that untags the field.

grabN :: forall n x xs. MemberAt n x xs => Many xs -> x Source #

Getter by index. Get the value of the field at index type-level Nat n

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil
grabN @1 x `shouldBe` False

Setter for single field

replace :: forall x y xs. UniqueMember x xs => Many xs -> y -> Many (Replace x y xs) Source #

Polymorphic setter by unique type. Set the field with type x, and replace with type y

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil
replace @Int x (Just True) `shouldBe` Just True ./ False ./ 'X' ./ Just 'O' ./ nil

replace' :: forall x xs. UniqueMember x xs => Many xs -> x -> Many xs Source #

Setter by unique type. Set the field with type x.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil
replace' @Int x 6 `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil

replaceL :: forall l y xs x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => Many xs -> y -> Many (Replace x y xs) Source #

Polymorphic setter by unique type. Set the field with type x, and replace with type y

let y = (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Tagged @"Hello" (6 :: Int) ./ nil
replaceL @Foo y (Tagged @Bar 'Y') shouldBe
    (5 :: Int) ./ False ./ Tagged Bar Y ./ Tagged Hello (6 :: Int) ./ nil
replaceL @"Hello" y (Tagged @"Hello" False) `shouldBe`
    (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Tagged @"Hello" False ./ nil

replaceL' :: forall l x xs. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => Many xs -> x -> Many xs Source #

Setter by unique label. Set the field with label l.

let y = (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Tagged @"Hello" (6 :: Int) ./ nil
replaceL' @Foo y (Tagged @Foo 'Y') `shouldBe`
    (5 :: Int) ./ False ./ Tagged @Foo 'Y' ./ Tagged @"Hello" (6 :: Int) ./ nil
replaceL' @"Hello" y (Tagged @"Hello" 7) `shouldBe`
    (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Tagged @"Hello" (7 :: Int) ./ nil

replaceTag :: forall l x y xs. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => Many xs -> y -> Many (Replace x (Tagged l y) xs) Source #

Variation of replaceL specialized to Tagged that automatically tags the value to be replaced.

replaceTag' :: forall l xs x. (UniqueLabelMember l xs, Tagged l x ~ KindAtLabel l xs) => Many xs -> x -> Many xs Source #

Variation of replaceL' specialized to Tagged that automatically tags the value to be replaced.

replaceN :: forall n x y xs. MemberAt n x xs => Many xs -> y -> Many (ReplaceIndex n x y xs) Source #

Polymorphic version of replaceN'

replaceN' :: forall n x xs. MemberAt n x xs => Many xs -> x -> Many xs Source #

Setter by index. Set the value of the field at index type-level Nat n

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil
replaceN' @0 x 7 shouldBe

Multiple fields

Getter for multiple fields

type Select (smaller :: [Type]) (larger :: [Type]) = AFoldable (CollectorAny (CaseSelect smaller larger) larger) (Maybe (Int, WrappedAny)) Source #

A friendlier type constraint synomyn for select

select :: forall smaller larger. Select smaller larger => Many larger -> Many smaller Source #

Construct a Many with a smaller number of fields than the original. Analogous to grab getter but for multiple fields.

This can also be used to reorder fields in the original Many.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil
select @'[Bool, Char] x `shouldBe` False ./ 'X' ./ nil

selectL :: forall ls smaller larger. (Select smaller larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => Many larger -> Many smaller Source #

A variation of select which selects by labels

let x = False ./ Tagged @"Hi" (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Bye" O ./ nil
selectL @'[Foo, Bar] x `shouldBe` Tagged @Foo False ./ Tagged @Bar 'X' ./ nil
selectL @'["Hi", "Bye"] x `shouldBe` Tagged @"Hi" (5 :: Int) ./ Tagged @"Bye" 'O' ./ nil

type SelectN (ns :: [Nat]) (smaller :: [Type]) (larger :: [Type]) = (AFoldable (CollectorAnyN (CaseSelectN ns smaller) 0 larger) (Maybe (Int, WrappedAny)), smaller ~ KindsAtIndices ns larger, IsDistinct ns) Source #

A friendlier type constraint synomyn for selectN

selectN :: forall ns smaller larger. SelectN ns smaller larger => Many larger -> Many smaller Source #

A variation of select which uses a Nat list n to specify how to reorder the fields, where

indices[branch_idx] = tree_idx@

This variation allows smaller or larger to contain indistinct since the mapping is specified by indicies.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil
selectN @'[5, 4, 0] x `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nil

Setter for multiple fields

type Amend smaller smaller' larger = (AFoldable (CollectorAny (CaseAmend larger) (Zip smaller smaller')) (Int, WrappedAny), IsDistinct smaller) Source #

A friendlier type constraint synomyn for amend

amend :: forall smaller smaller' larger larger'. (Amend smaller smaller' larger, larger' ~ Replaces smaller smaller' larger) => Many larger -> Many smaller' -> Many larger' Source #

Polymorphic version of amend'. Analogous to replace setter but for multiple fields.

type Amend' smaller larger = (AFoldable (CollectorAny (CaseAmend' larger) smaller) (Int, WrappedAny), IsDistinct smaller) Source #

A friendlier type constraint synomyn for amend'

amend' :: forall smaller larger. Amend' smaller larger => Many larger -> Many smaller -> Many larger Source #

Sets the subset of Many in the larger Many. Analogous to replace setter but for multiple fields.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil
amend' @'[Int, Maybe Char] x ((6 :: Int) ./ Just 'P' ./ nil) `shouldBe`
    (6 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nil

amendL :: forall ls smaller smaller' larger larger'. (Amend smaller smaller' larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger, larger' ~ Replaces smaller smaller' larger) => Many larger -> Many smaller' -> Many larger' Source #

A variation of amend which amends via labels.

let x = False ./ Tagged @"Hi" (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar X ./ Tagged @"Bye" 'O' ./ nil
amendL @'[Foo, Bar] x ('Y' ./ True ./ nil) `shouldBe`
    False ./ Tagged @"Hi" (5 :: Int) ./ 'Y' ./ True ./ Tagged @"Bye" 'O' ./ nil
amendL @'["Hi", "Bye"] x (True ./ Tagged @"Changed" True ./ nil) `shouldBe`
    False ./ True ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Changed" True ./ nil

amendL' :: forall ls smaller larger. (Amend' smaller larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => Many larger -> Many smaller -> Many larger Source #

A variation of amend' which amends via labels.

let x = False . Tagged @"Hi" (5 :: Int) . Tagged @Foo False . Tagged @Bar 'X' . Tagged @"Bye" 'O' ./ nil
amendL @'[Foo, Bar] x (Tagged @Foo True . Tagged @Bar 'Y' . nil) shouldBe
    False . Tagged @"Hi" (5 :: Int) . Tagged @Foo True . Tagged @Bar 'Y' . Tagged @"Bye" 'O' ./ nil
amendL @'["Hi", "Bye"] x (Tagged @"Hi" (6 :: Int) . Tagged @"Bye" 'P' . nil) shouldBe
    False . Tagged @"Hi" (6 :: Int) . Tagged @Foo False . Tagged @Bar 'X' . Tagged @"Bye" 'P' ./ nil

type AmendN ns smaller smaller' larger = (AFoldable (CollectorAnyN (CaseAmendN ns larger) 0 (Zip smaller smaller')) (Int, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns) Source #

A friendlier type constraint synomyn for amendN

amendN :: forall ns smaller smaller' larger larger'. (AmendN ns smaller smaller' larger, larger' ~ ReplacesIndex ns smaller' larger) => Many larger -> Many smaller' -> Many larger' Source #

A polymorphic variation of amendN'

type AmendN' ns smaller larger = (AFoldable (CollectorAnyN (CaseAmendN' ns larger) 0 smaller) (Int, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns) Source #

A friendlier type constraint synomyn for amendN'

amendN' :: forall ns smaller larger. AmendN' ns smaller larger => Many larger -> Many smaller -> Many larger Source #

A variation of amend' which uses a Nat list n to specify how to reorder the fields, where

indices[branch_idx] = tree_idx@

This variation allows smaller or larger to contain indistinct since the mapping is specified by indicies.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil
amendN' @'[5, 4, 0] x (Just 'B' ./ (8 :: Int) ./ (4 ::Int) ./ nil) `shouldBe`
    (4 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just 'B' ./ nil

Destruction

By type

type Collect c r (xs :: [Type]) = (AFoldable (Collector c xs) r, Case (c r) xs) Source #

A friendlier type constraint synomyn for collect and forMany

data Collector c (xs :: [Type]) r Source #

Collects the output from case'ing each field in a Many. Uses Reiterate to prepare the Case to accept the next type in the xs typelist.

Internally, this holds the left-over [(k, v)] from the original Many for the remaining typelist xs.

That is, the first v in the (k, v) is of type x, and the length of the list is equal to the length of xs.

Instances

(Case (c r) ((:) Type x xs), Reiterate (c r) ((:) Type x xs), AFoldable (Collector * c xs) r, (~) * r (CaseResult Type * (c r) x)) => AFoldable (Collector * c ((:) Type x xs)) r Source #

Folds values by reiterateing Cases through the xs typelist.

Methods

afoldr :: (r -> b -> b) -> b -> Collector * c ((Type ': x) xs) r -> b Source #

AFoldable (Collector * c ([] Type)) r Source #

nill case that doesn't even use case', so that an instance of Case '[] is not needed.

Methods

afoldr :: (r -> b -> b) -> b -> Collector * c [Type] r -> b Source #

forMany :: Collect c r xs => c r xs -> Many xs -> Collector c xs r Source #

Folds any Many, even with indistinct types. Given distinct handlers for the fields in Many, create AFoldable of the results of running the handlers over the fields in Many.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil
    y = show @Int ./ show @Char ./ show @(Maybe Char) ./ show @Bool ./ nil
afoldr (:) [] (forMany (cases y) x) `shouldBe`
    ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"]

collect :: Collect c r xs => Many xs -> c r xs -> Collector c xs r Source #

This is flip forMany

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil
    y = show @Int ./ show @Char ./ show @(Maybe Char) ./ show @Bool ./ nil
afoldr (:) [] (collect x (cases y)) `shouldBe`
    ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"]

By Nat index offset

type CollectN c r (n :: Nat) (xs :: [Type]) = (AFoldable (CollectorN c n xs) r, Case (c r n) xs) Source #

A friendlier type constraint synomyn for collect and forMany

data CollectorN c (n :: Nat) (xs :: [Type]) r Source #

A variation of Collector which uses ReiterateN instead of Reiterate

Instances

(Case (c r n) ((:) Type x xs), ReiterateN (c r) n ((:) Type x xs), AFoldable (CollectorN * c ((+) n 1) xs) r, (~) * r (CaseResult Type * (c r n) x)) => AFoldable (CollectorN * c n ((:) Type x xs)) r Source #

Folds values by reiterateing Emitters through the xs typelist.

Methods

afoldr :: (r -> b -> b) -> b -> CollectorN * c n ((Type ': x) xs) r -> b Source #

AFoldable (CollectorN * c n ([] Type)) r Source #

nill case that doesn't even use case', so that an instance of Case '[] is not needed.

Methods

afoldr :: (r -> b -> b) -> b -> CollectorN * c n [Type] r -> b Source #

forManyN :: CollectN c r n xs => c r n xs -> Many xs -> CollectorN c n xs r Source #

Folds any Many, even with indistinct types. Given index handlers for the fields in Many, create AFoldable of the results of running the handlers over the fields in Many.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil
    y = show @Int ./ show @Bool ./ show @Char ./ show @(Maybe Char) ./ show @Int ./ show @(Maybe Char) ./ nil
afoldr (:) [] (forManyN (casesN y) x) `shouldBe`
    ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"]

collectN :: CollectN c r n xs => Many xs -> c r n xs -> CollectorN c n xs r Source #

This is flip forManyN

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil
    y = show @Int ./ show @Bool ./ show @Char ./ show @(Maybe Char) ./ show @Int ./ show @(Maybe Char) ./ nil
afoldr (:) [] (collectN x (casesN y)) `shouldBe`
    ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"]