data-diverse-0.1.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 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 (Offset, Map Int 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

AFoldable (Collector * (EmitEqMany *) xs) Bool => Eq (Many xs) Source #

Two Manys are equal if all their fields equal

Methods

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

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

(Eq (Many xs), AFoldable (Collector * (EmitOrdMany *) xs) Ordering) => 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 #

AFoldable (Collector0 * (EmitReadMany *) xs) (ReadPrec [(Key, WrappedAny)]) => Read (Many xs) Source #
read "5 . False . X . Just O . nul" == (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul
AFoldable (Collector0 * (EmitShowMany *) xs) ShowS => Show (Many xs) Source #
read "5 . False . X . Just O . nul" == (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul

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 #

Inferred role is phantom which is incorrect

A terminating Generic instance encoded as a nul.

Associated Types

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

Methods

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

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

type Rep (Many ((:) Type x xs)) Source # 
type Rep (Many ((:) Type x xs)) = D1 (MetaData "Many" "Data.Diverse.Many.Internal" PackageId False) ((:*:) (Rec0 x) (Rec0 (Many xs)))
type Rep (Many ([] Type)) Source # 
type Rep (Many ([] Type)) = D1 (MetaData "Many" "Data.Diverse.Many.Internal" PackageId False) 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

_Many :: IsMany t xs a => Iso' (Many xs) (t xs a) Source #

_Many = iso fromMany toMany

_Many' :: IsMany Tagged xs a => Iso' (Many xs) a Source #

_Many' = iso fromMany' toMany'

Construction

nul :: Many '[] infixr 5 Source #

Analogous to null. Named nul to avoid conflicting with null.

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

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

snoc 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 #

append mnemonic: cons ./ with an extra slash (meaning Many) in front.

Simple queries

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

fetch :: 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' ./ nul
fetch @Int x `shouldBe` 5

(.^.) :: forall x xs proxy. UniqueMember x xs => Many xs -> proxy x -> x infixl 8 Source #

infix version of fetch, with a extra proxy to carry the destination type.

Mnemonic: Like 'Control.Lens.(^.)' but with an extra . in front.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul
x .^. (Proxy @Int) `shouldBe` 5

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

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

getchN (Proxy @2) t

Setter for single field

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' ./ nul
replace @Int x 6 `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul

(.~.) :: forall x xs. UniqueMember x xs => Many xs -> x -> Many xs infixl 1 Source #

infix version of replace

Mnemonic: Like a back to front 'Control.Lens.(.~)' with an extra . in front.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul
(x .~. (6 :: Int)) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul

replaceN :: forall n x xs proxy. MemberAt n x xs => proxy n -> 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' ./ nul
replaceN @0 Proxy x 7 shouldBe

Lens for a single field

item :: forall x xs. UniqueMember x xs => Lens' (Many xs) x Source #

fetch (view item) and replace (set item) in Lens' form.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul
x ^. item @Int `shouldBe` 5
(x & item @Int .~ 6) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul

itemN :: forall n x xs proxy. MemberAt n x xs => proxy n -> Lens' (Many xs) x Source #

fetchN (view item) and replaceN (set item) in Lens' form.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul
x ^. itemN (Proxy @0) `shouldBe` 5
(x & itemN (Proxy @0) .~ 6) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul

Multiple fields

Getter for multiple fields

type Narrow smaller larger = AFoldable (Collector (Via (CaseNarrow smaller larger)) larger) [(Key, WrappedAny)] Source #

A friendlier type constraint synomyn for narrow

narrow :: forall smaller larger. Narrow smaller larger => Many larger -> Many smaller Source #

Construct a Many with a smaller number of fields than the original. Analogous to fetch 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' ./ nul
narrow @'[Bool, Char] x `shouldBe` False ./ 'X' ./ nul

(\^.) :: forall smaller larger proxy. Narrow smaller larger => Many larger -> proxy smaller -> Many smaller infixl 8 Source #

infix version of narrow, with a extra proxy to carry the smaller type.

Mnemonic: Like 'Control.Lens.(^.)' but with an extra '\' (narrow to the right) in front.

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

type NarrowN ns smaller larger = (AFoldable (CollectorN (ViaN (CaseNarrowN ns smaller)) 0 larger) [(Key, WrappedAny)], smaller ~ KindsAtIndices ns larger, IsDistinct ns) Source #

A friendlier type constraint synomyn for narrowN

narrowN :: forall ns smaller larger proxy. NarrowN ns smaller larger => proxy ns -> Many larger -> Many smaller Source #

A variation of narrow 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' ./ nul
narrowN (Proxy @'[5, 4, 0]) x `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nul

Setter for multiple fields

type Amend smaller larger = (AFoldable (Collector (Via (CaseAmend larger)) smaller) (Key, 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' ./ nul
amend @'[Int, Maybe Char] x ((6 :: Int) ./ Just 'P' ./ nul) `shouldBe`
    (6 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul

(\~.) :: forall smaller larger. Amend smaller larger => Many larger -> Many smaller -> Many larger infixl 1 Source #

infix version of amend. Mnemonic: Like 'Control.Lens.(.~)' but with an extra '\' (narrow to the right) in front.

Mnemonic: Like backwards 'Control.Lens.(^.)' but with an extra '\' (narrow to the right) in front.

let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul
(x \~. (6 :: Int) ./ Just 'P' ./ nul) `shouldBe`
    (6 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul

type AmendN ns smaller larger = (AFoldable (CollectorN (ViaN (CaseAmendN ns larger)) 0 smaller) (Key, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns) Source #

A friendlier type constraint synomyn for amendN

amendN :: forall ns smaller larger proxy. AmendN ns smaller larger => proxy ns -> 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' ./ nul
amendN (Proxy @'[5, 4, 0]) x (Just 'B' ./ (8 :: Int) ./ (4 ::Int) ./ nul) `shouldBe`
    (4 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just 'B' ./ nul

Lens for multiple fields

project :: forall smaller larger. (Narrow smaller larger, Amend smaller larger) => Lens' (Many larger) (Many smaller) Source #

narrow (view project) and amend (set project) in Lens' form.

project = lens narrow amend
let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul
x ^. (project @'[Int, Maybe Char]) `shouldBe` (5 :: Int) ./ Just 'O' ./ nul
(x & (project @'[Int, Maybe Char]) .~ ((6 :: Int) ./ Just P ./ nul)) `shouldBe`
    (6 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul

projectN :: forall ns smaller larger proxy. (NarrowN ns smaller larger, AmendN ns smaller larger) => proxy ns -> Lens' (Many larger) (Many smaller) Source #

narrowN (view projectN) and amendN (set projectN) in Lens' form.

projectN = lens narrowN amendN
let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul
x ^. (projectN @'[5, 4, 0] Proxy) `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nul
(x & (projectN @'[5, 4, 0] Proxy) .~ (Just 'B' ./ (8 :: Int) ./ (4 ::Int) ./ nul)) `shouldBe`
    (4 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just 'B' ./ nul

Destruction

By type

data Via c xs r Source #

Wraps a Case into an instance of Emit, reiterateing and feeding Case with the value from the Many and emitting the results.

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

Reiterate k c ((:) Type x xs) => Reiterate k (Via k c) ((:) Type x xs) Source # 

Methods

reiterate :: (Type ': x) xs xs r -> (Type ': x) xs (Tail Type xs) r Source #

Case c ((:) Type x xs) r => Emit Type (Via * c) ((:) Type x xs) r Source # 

Methods

emit :: (Type ': x) xs r r -> r Source #

via :: c xs r -> Many xs -> Via c xs r Source #

Creates an Via safely, so that the invariant of "typelist to the value list type and size" holds.

forMany :: c xs r -> Many xs -> Collector (Via c) xs r Source #

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

The Collector is AFoldable to combine the results.

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

collect :: Many xs -> c xs r -> Collector (Via c) xs r Source #

This is flip forMany

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

By Nat index offset

data ViaN c n xs r Source #

A variation of Via which reiterateN instead.

Instances

ReiterateN k c n ((:) Type x xs) => ReiterateN k (ViaN k c) n ((:) Type x xs) Source # 

Methods

reiterateN :: n ((Type ': x) xs) xs r -> n ((Type ': x) xs + 1) (Tail Type xs) r Source #

Case (c n) ((:) Type x xs) r => Emit Type (ViaN * c n) ((:) Type x xs) r Source # 

Methods

emit :: (Type ': x) xs r r -> r Source #

viaN :: c n xs r -> Many xs -> ViaN c n xs r Source #

Creates an ViaN safely, so that the invariant of "typelist to the value list type and size" holds.

forManyN :: c n xs r -> Many xs -> CollectorN (ViaN c) n xs r Source #

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

The CollectorN is AFoldable to combine the results.

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

collectN :: Many xs -> c n xs r -> CollectorN (ViaN c) n xs r Source #

This is flip forManyN

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