packages feed

data-diverse 0.3.0.0 → 0.4.0.0

raw patch · 13 files changed

+987/−607 lines, 13 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Diverse.Case: caseAny :: Case c xs r => c xs r -> Any -> r
- Data.Diverse.Collector: Collector :: (e xs r) -> Collector e r
- Data.Diverse.Collector: Collector0 :: (e xs r) -> Collector0 e r
- Data.Diverse.Collector: CollectorN :: (e n xs r) -> CollectorN e r
- Data.Diverse.Collector: CollectorN0 :: (e n xs r) -> CollectorN0 e r
- Data.Diverse.Collector: instance (Data.Diverse.Emit.Emit (e n) (x : xs) r, Data.Diverse.Reiterate.ReiterateN e n (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.CollectorN e (n GHC.TypeLits.+ 1) xs) r) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.CollectorN e n (x : xs)) r
- Data.Diverse.Collector: instance (Data.Diverse.Emit.Emit (e n) (x : xs) r, Data.Diverse.Reiterate.ReiterateN e n (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.CollectorN0 e (n GHC.TypeLits.+ 1) xs) r) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.CollectorN0 e n (x : xs)) r
- Data.Diverse.Collector: instance (Data.Diverse.Emit.Emit e (x : xs) r, Data.Diverse.Reiterate.Reiterate e (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.Collector e xs) r) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.Collector e (x : xs)) r
- Data.Diverse.Collector: instance (Data.Diverse.Emit.Emit e (x : xs) r, Data.Diverse.Reiterate.Reiterate e (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.Collector0 e xs) r) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.Collector0 e (x : xs)) r
- Data.Diverse.Collector: instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.Collector e '[]) r
- Data.Diverse.Collector: instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.CollectorN e n '[]) r
- Data.Diverse.Collector: instance Data.Diverse.Emit.Emit (e n) '[] r => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.CollectorN0 e n '[]) r
- Data.Diverse.Collector: instance Data.Diverse.Emit.Emit e '[] r => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.Collector0 e '[]) r
- Data.Diverse.Collector: newtype Collector e (xs :: [Type]) r
- Data.Diverse.Collector: newtype Collector0 e (xs :: [Type]) r
- Data.Diverse.Collector: newtype CollectorN e (n :: Nat) (xs :: [Type]) r
- Data.Diverse.Collector: newtype CollectorN0 e (n :: Nat) (xs :: [Type]) r
- Data.Diverse.Emit: class Emit e (xs :: [k]) r
- Data.Diverse.Emit: emit :: Emit e xs r => e xs r -> r
- Data.Diverse.Many: data Via c (xs :: [Type]) r
- Data.Diverse.Many: data ViaN c (n :: Nat) (xs :: [Type]) r
- Data.Diverse.Many: nul :: Many '[]
- Data.Diverse.Many: via :: c xs r -> Many xs -> Via c xs r
- Data.Diverse.Many: viaN :: c n xs r -> Many xs -> ViaN c n xs r
- Data.Diverse.Many.Internal: data Via c (xs :: [Type]) r
- Data.Diverse.Many.Internal: data ViaN c (n :: Nat) (xs :: [Type]) r
- Data.Diverse.Many.Internal: instance (Data.Diverse.Type.UniqueIfExists smaller x larger, Data.Diverse.Type.MaybeUniqueMember x smaller) => Data.Diverse.Case.Case (Data.Diverse.Many.Internal.CaseSelect smaller larger) (x : xs) [(Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)]
- Data.Diverse.Many.Internal: instance (GHC.Classes.Eq (Data.Diverse.Many.Internal.Many xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.Collector Data.Diverse.Many.Internal.EmitOrdMany xs) GHC.Types.Ordering) => GHC.Classes.Ord (Data.Diverse.Many.Internal.Many xs)
- Data.Diverse.Many.Internal: instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.Collector Data.Diverse.Many.Internal.EmitEqMany xs) GHC.Types.Bool => GHC.Classes.Eq (Data.Diverse.Many.Internal.Many xs)
- Data.Diverse.Many.Internal: instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.Collector0 Data.Diverse.Many.Internal.EmitReadMany xs) (Text.ParserCombinators.ReadPrec.ReadPrec [(Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)]) => GHC.Read.Read (Data.Diverse.Many.Internal.Many xs)
- Data.Diverse.Many.Internal: instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.Collector0 Data.Diverse.Many.Internal.EmitShowMany xs) GHC.Show.ShowS => GHC.Show.Show (Data.Diverse.Many.Internal.Many xs)
- Data.Diverse.Many.Internal: instance Data.Diverse.Case.Case (c n) (x : xs) r => Data.Diverse.Emit.Emit (Data.Diverse.Many.Internal.ViaN c n) (x : xs) r
- Data.Diverse.Many.Internal: instance Data.Diverse.Case.Case c (x : xs) r => Data.Diverse.Emit.Emit (Data.Diverse.Many.Internal.Via c) (x : xs) r
- Data.Diverse.Many.Internal: instance Data.Diverse.Emit.Emit Data.Diverse.Many.Internal.EmitReadMany '[] (Text.ParserCombinators.ReadPrec.ReadPrec [(Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)])
- Data.Diverse.Many.Internal: instance Data.Diverse.Emit.Emit Data.Diverse.Many.Internal.EmitShowMany '[] GHC.Show.ShowS
- Data.Diverse.Many.Internal: instance Data.Diverse.Reiterate.Reiterate Data.Diverse.Many.Internal.EmitEqMany (x : xs)
- Data.Diverse.Many.Internal: instance Data.Diverse.Reiterate.Reiterate Data.Diverse.Many.Internal.EmitOrdMany (x : xs)
- Data.Diverse.Many.Internal: instance Data.Diverse.Reiterate.Reiterate Data.Diverse.Many.Internal.EmitReadMany (x : xs)
- Data.Diverse.Many.Internal: instance Data.Diverse.Reiterate.Reiterate Data.Diverse.Many.Internal.EmitShowMany (x : xs)
- Data.Diverse.Many.Internal: instance Data.Diverse.Type.MaybeMemberAt (Data.Diverse.Type.PositionOf n indices) x smaller => Data.Diverse.Case.Case (Data.Diverse.Many.Internal.CaseSelectN indices smaller n) (x : xs) [(Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)]
- Data.Diverse.Many.Internal: instance Data.Diverse.Type.MemberAt (Data.Diverse.Type.KindAtIndex n indices) x larger => Data.Diverse.Case.Case (Data.Diverse.Many.Internal.CaseAmendN indices larger n) (x : xs) (Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)
- Data.Diverse.Many.Internal: instance Data.Diverse.Type.MemberAt (Data.Diverse.Type.KindAtIndex n indices) x larger => Data.Diverse.Case.Case (Data.Diverse.Many.Internal.CaseAmendN' indices larger n) ((x, y) : zs) (Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)
- Data.Diverse.Many.Internal: instance Data.Diverse.Type.UniqueMember x larger => Data.Diverse.Case.Case (Data.Diverse.Many.Internal.CaseAmend larger) (x : xs) (Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)
- Data.Diverse.Many.Internal: instance Data.Diverse.Type.UniqueMember x larger => Data.Diverse.Case.Case (Data.Diverse.Many.Internal.CaseAmend' larger) ((x, y) : zs) (Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)
- Data.Diverse.Many.Internal: instance GHC.Classes.Eq Data.Diverse.Many.Internal.Key
- Data.Diverse.Many.Internal: instance GHC.Classes.Eq x => Data.Diverse.Emit.Emit Data.Diverse.Many.Internal.EmitEqMany (x : xs) GHC.Types.Bool
- Data.Diverse.Many.Internal: instance GHC.Classes.Ord Data.Diverse.Many.Internal.Key
- Data.Diverse.Many.Internal: instance GHC.Classes.Ord x => Data.Diverse.Emit.Emit Data.Diverse.Many.Internal.EmitOrdMany (x : xs) GHC.Types.Ordering
- Data.Diverse.Many.Internal: instance GHC.Read.Read x => Data.Diverse.Emit.Emit Data.Diverse.Many.Internal.EmitReadMany (x : xs) (Text.ParserCombinators.ReadPrec.ReadPrec [(Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)])
- Data.Diverse.Many.Internal: instance GHC.Show.Show Data.Diverse.Many.Internal.Key
- Data.Diverse.Many.Internal: instance GHC.Show.Show x => Data.Diverse.Emit.Emit Data.Diverse.Many.Internal.EmitShowMany (x : xs) GHC.Show.ShowS
- Data.Diverse.Many.Internal: instance forall k (c :: GHC.Types.Nat -> [GHC.Types.Type] -> k -> *) (n :: GHC.Types.Nat) x (xs :: [GHC.Types.Type]). Data.Diverse.Reiterate.ReiterateN c n (x : xs) => Data.Diverse.Reiterate.ReiterateN (Data.Diverse.Many.Internal.ViaN c) n (x : xs)
- Data.Diverse.Many.Internal: instance forall k (c :: [GHC.Types.Type] -> k -> *) x (xs :: [GHC.Types.Type]). Data.Diverse.Reiterate.Reiterate c (x : xs) => Data.Diverse.Reiterate.Reiterate (Data.Diverse.Many.Internal.Via c) (x : xs)
- Data.Diverse.Many.Internal: nul :: Many '[]
- Data.Diverse.Many.Internal: via :: c xs r -> Many xs -> Via c xs r
- Data.Diverse.Many.Internal: viaN :: c n xs r -> Many xs -> ViaN c n xs r
- Data.Diverse.Type: type MaybeUniqueMember x xs = (Unique x xs, KnownNat (PositionOf x xs))
- Data.Diverse.Which.Internal: instance (Data.Diverse.Type.MaybeUniqueMember x branch, comp ~ Data.Diverse.Type.Complement tree branch, Data.Diverse.Type.MaybeUniqueMember x comp, Data.Diverse.Type.Unique x tree) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseReinterpret branch tree) (x : tree') (Data.Either.Either (Data.Diverse.Which.Internal.Which comp) (Data.Diverse.Which.Internal.Which branch))
- Data.Diverse.Which.Internal: instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Collector.Collector Data.Diverse.Which.Internal.EmitReadWhich (x : xs)) (Text.ParserCombinators.ReadPrec.ReadPrec (GHC.Types.Int, Data.Diverse.Which.Internal.WrappedAny)) => GHC.Read.Read (Data.Diverse.Which.Internal.Which (x : xs))
- Data.Diverse.Which.Internal: instance Data.Diverse.Reiterate.Reiterate Data.Diverse.Which.Internal.EmitReadWhich (x : xs)
- Data.Diverse.Which.Internal: instance Data.Diverse.Type.MaybeMemberAt (Data.Diverse.Type.PositionOf n indices) x branch => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseReinterpretN indices n) (x : tree) (GHC.Base.Maybe (Data.Diverse.Which.Internal.Which branch))
- Data.Diverse.Which.Internal: instance GHC.Read.Read x => Data.Diverse.Emit.Emit Data.Diverse.Which.Internal.EmitReadWhich (x : xs) (Text.ParserCombinators.ReadPrec.ReadPrec (GHC.Types.Int, Data.Diverse.Which.Internal.WrappedAny))
+ Data.Diverse.Many: amendL :: forall ls smaller larger proxy. (Amend smaller larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Many larger -> Many smaller -> Many larger
+ Data.Diverse.Many: amendL' :: forall ls smaller smaller' larger proxy zipped. (Amend' smaller smaller' larger zipped, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger)
+ Data.Diverse.Many: fetchL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> x
+ Data.Diverse.Many: itemL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Lens' (Many xs) x
+ Data.Diverse.Many: itemL' :: forall l y xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Lens (Many xs) (Many (Replace x y xs)) x y
+ Data.Diverse.Many: nil :: Many '[]
+ Data.Diverse.Many: projectL :: forall ls smaller larger proxy. (Select smaller larger, Amend smaller larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Lens' (Many larger) (Many smaller)
+ Data.Diverse.Many: projectL' :: forall ls smaller smaller' larger proxy zipped. (Select smaller larger, Amend' smaller smaller' larger zipped, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')
+ Data.Diverse.Many: replaceL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> x -> Many xs
+ Data.Diverse.Many: replaceL' :: forall l y xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> y -> Many (Replace x y xs)
+ Data.Diverse.Many: selectL :: forall ls smaller larger proxy. (Select smaller larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Many larger -> Many smaller
+ Data.Diverse.Many.Internal: amendL :: forall ls smaller larger proxy. (Amend smaller larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Many larger -> Many smaller -> Many larger
+ Data.Diverse.Many.Internal: amendL' :: forall ls smaller smaller' larger proxy zipped. (Amend' smaller smaller' larger zipped, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger)
+ Data.Diverse.Many.Internal: fetchL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> x
+ Data.Diverse.Many.Internal: instance (Data.Diverse.Case.Case (c n) (x : xs) r, Data.Diverse.Reiterate.ReiterateN c n (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorN c (n GHC.TypeLits.+ 1) xs) r) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorN c n (x : xs)) r
+ Data.Diverse.Many.Internal: instance (Data.Diverse.Case.Case c (x : xs) r, Data.Diverse.Reiterate.Reiterate c (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.Collector c xs) r) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.Collector c (x : xs)) r
+ Data.Diverse.Many.Internal: instance (Data.Diverse.Many.Internal.CaseAny (c n) (x : xs) r, Data.Diverse.Reiterate.ReiterateN c n (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAnyN c (n GHC.TypeLits.+ 1) xs) r) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAnyN c n (x : xs)) r
+ Data.Diverse.Many.Internal: instance (Data.Diverse.Many.Internal.CaseAny c (x : xs) r, Data.Diverse.Reiterate.Reiterate c (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAny c xs) r) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAny c (x : xs)) r
+ Data.Diverse.Many.Internal: instance (Data.Diverse.Type.MaybeMemberAt n' x smaller, n' ~ Data.Diverse.Type.PositionOf n indices) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseSelectN indices smaller n) (x : xs) (GHC.Base.Maybe (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny))
+ Data.Diverse.Many.Internal: instance (Data.Diverse.Type.MemberAt n' x larger, n' ~ Data.Diverse.Type.KindAtIndex n indices) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmendN indices larger n) (x : xs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
+ Data.Diverse.Many.Internal: instance (Data.Diverse.Type.MemberAt n' x larger, n' ~ Data.Diverse.Type.KindAtIndex n indices) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmendN' indices larger n) ((x, y) : zs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
+ Data.Diverse.Many.Internal: instance (Data.Diverse.Type.UniqueIfExists smaller x larger, Data.Diverse.Type.MaybeUniqueMemberAt n x smaller) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseSelect smaller larger) (x : xs) (GHC.Base.Maybe (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny))
+ Data.Diverse.Many.Internal: instance (GHC.Classes.Eq x, GHC.Classes.Eq (Data.Diverse.Many.Internal.Many_ xs)) => GHC.Classes.Eq (Data.Diverse.Many.Internal.Many_ (x : xs))
+ Data.Diverse.Many.Internal: instance (GHC.Classes.Ord x, GHC.Classes.Ord (Data.Diverse.Many.Internal.Many_ xs)) => GHC.Classes.Ord (Data.Diverse.Many.Internal.Many_ (x : xs))
+ Data.Diverse.Many.Internal: instance (GHC.Read.Read x, GHC.Read.Read (Data.Diverse.Many.Internal.Many_ xs)) => GHC.Read.Read (Data.Diverse.Many.Internal.Many_ (x : xs))
+ Data.Diverse.Many.Internal: instance (GHC.Show.Show x, GHC.Show.Show (Data.Diverse.Many.Internal.Many_ xs)) => GHC.Show.Show (Data.Diverse.Many.Internal.Many_ (x : xs))
+ Data.Diverse.Many.Internal: instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.Collector c '[]) r
+ Data.Diverse.Many.Internal: instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAny c '[]) r
+ Data.Diverse.Many.Internal: instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorN c n '[]) r
+ Data.Diverse.Many.Internal: instance Data.Diverse.Type.UniqueMemberAt n x larger => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmend larger) (x : xs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
+ Data.Diverse.Many.Internal: instance Data.Diverse.Type.UniqueMemberAt n x larger => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmend' larger) ((x, y) : zs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
+ Data.Diverse.Many.Internal: instance GHC.Classes.Eq (Data.Diverse.Many.Internal.Many_ '[])
+ Data.Diverse.Many.Internal: instance GHC.Classes.Eq (Data.Diverse.Many.Internal.Many_ xs) => GHC.Classes.Eq (Data.Diverse.Many.Internal.Many xs)
+ Data.Diverse.Many.Internal: instance GHC.Classes.Ord (Data.Diverse.Many.Internal.Many_ '[])
+ Data.Diverse.Many.Internal: instance GHC.Classes.Ord (Data.Diverse.Many.Internal.Many_ xs) => GHC.Classes.Ord (Data.Diverse.Many.Internal.Many xs)
+ Data.Diverse.Many.Internal: instance GHC.Read.Read (Data.Diverse.Many.Internal.Many_ '[])
+ Data.Diverse.Many.Internal: instance GHC.Read.Read (Data.Diverse.Many.Internal.Many_ xs) => GHC.Read.Read (Data.Diverse.Many.Internal.Many xs)
+ Data.Diverse.Many.Internal: instance GHC.Show.Show (Data.Diverse.Many.Internal.Many_ '[])
+ Data.Diverse.Many.Internal: instance GHC.Show.Show (Data.Diverse.Many.Internal.Many_ xs) => GHC.Show.Show (Data.Diverse.Many.Internal.Many xs)
+ Data.Diverse.Many.Internal: instance forall k (c :: k -> [GHC.Types.Type] -> * -> *) (n :: k) r. Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAnyN c n '[]) r
+ Data.Diverse.Many.Internal: itemL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Lens' (Many xs) x
+ Data.Diverse.Many.Internal: itemL' :: forall l y xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Lens (Many xs) (Many (Replace x y xs)) x y
+ Data.Diverse.Many.Internal: nil :: Many '[]
+ Data.Diverse.Many.Internal: projectL :: forall ls smaller larger proxy. (Select smaller larger, Amend smaller larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Lens' (Many larger) (Many smaller)
+ Data.Diverse.Many.Internal: projectL' :: forall ls smaller smaller' larger proxy zipped. (Select smaller larger, Amend' smaller smaller' larger zipped, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')
+ Data.Diverse.Many.Internal: replaceL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> x -> Many xs
+ Data.Diverse.Many.Internal: replaceL' :: forall l y xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> y -> Many (Replace x y xs)
+ Data.Diverse.Many.Internal: selectL :: forall ls smaller larger proxy. (Select smaller larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Many larger -> Many smaller
+ Data.Diverse.Type: type MaybeUniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ PositionOf x xs)
+ Data.Diverse.Type: type UniqueLabel (l :: k1) (xs :: [k]) = UniqueLabelImpl xs l xs
+ Data.Diverse.Type: type UniqueLabelMember l xs = (UniqueLabel l xs, KnownNat (IndexOf (KindAtLabel l xs) xs))
+ Data.Diverse.Type: type UniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ IndexOf x xs)
+ Data.Diverse.Which: diversifyL :: forall ls tree branch proxy. (Diversify tree branch, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) => proxy ls -> Which branch -> Which tree
+ Data.Diverse.Which: facetL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Prism' (Which xs) x
+ Data.Diverse.Which: injectL :: forall ls branch tree proxy. (Diversify tree branch, Reinterpret branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) => proxy ls -> Prism' (Which tree) (Which branch)
+ Data.Diverse.Which: pickL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> x -> Which xs
+ Data.Diverse.Which: reinterpretL :: forall ls branch tree proxy. (Reinterpret branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) => proxy ls -> Which tree -> Either (Which (Complement tree branch)) (Which branch)
+ Data.Diverse.Which: trialL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Which xs -> Either (Which (Without x xs)) x
+ Data.Diverse.Which.Internal: diversifyL :: forall ls tree branch proxy. (Diversify tree branch, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) => proxy ls -> Which branch -> Which tree
+ Data.Diverse.Which.Internal: facetL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Prism' (Which xs) x
+ Data.Diverse.Which.Internal: injectL :: forall ls branch tree proxy. (Diversify tree branch, Reinterpret branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) => proxy ls -> Prism' (Which tree) (Which branch)
+ Data.Diverse.Which.Internal: instance (Data.Diverse.Type.MaybeMemberAt n' x branch, n' ~ Data.Diverse.Type.PositionOf n indices) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseReinterpretN indices n) (x : tree) (GHC.Base.Maybe (Data.Diverse.Which.Internal.Which branch))
+ Data.Diverse.Which.Internal: instance (Data.Diverse.Type.MaybeUniqueMemberAt n x branch, comp ~ Data.Diverse.Type.Complement tree branch, Data.Diverse.Type.MaybeUniqueMemberAt n' x comp, Data.Diverse.Type.Unique x tree) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseReinterpret branch tree) (x : tree') (Data.Either.Either (Data.Diverse.Which.Internal.Which comp) (Data.Diverse.Which.Internal.Which branch))
+ Data.Diverse.Which.Internal: instance (GHC.Read.Read x, Data.Diverse.Which.Internal.WhichRead (Data.Diverse.Which.Internal.Which_ (x' : xs))) => Data.Diverse.Which.Internal.WhichRead (Data.Diverse.Which.Internal.Which_ (x : x' : xs))
+ Data.Diverse.Which.Internal: instance Data.Diverse.Which.Internal.WhichRead (Data.Diverse.Which.Internal.Which_ (x : xs)) => GHC.Read.Read (Data.Diverse.Which.Internal.Which (x : xs))
+ Data.Diverse.Which.Internal: instance GHC.Read.Read x => Data.Diverse.Which.Internal.WhichRead (Data.Diverse.Which.Internal.Which_ '[x])
+ Data.Diverse.Which.Internal: pickL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> x -> Which xs
+ Data.Diverse.Which.Internal: reinterpretL :: forall ls branch tree proxy. (Reinterpret branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) => proxy ls -> Which tree -> Either (Which (Complement tree branch)) (Which branch)
+ Data.Diverse.Which.Internal: trialL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Which xs -> Either (Which (Without x xs)) x
- Data.Diverse.Case: class Case c (xs :: [Type]) r where case' c v = caseAny c (unsafeCoerce v) caseAny c v = case' c (unsafeCoerce v)
+ Data.Diverse.Case: class Case c (xs :: [Type]) r
- Data.Diverse.Many: amend' :: forall smaller smaller' larger. Amend' smaller smaller' larger => Proxy smaller -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger)
+ Data.Diverse.Many: amend' :: forall smaller smaller' larger proxy zipped. Amend' smaller smaller' larger zipped => proxy smaller -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger)
- Data.Diverse.Many: amendN' :: forall ns smaller smaller' larger proxy. (AmendN' ns smaller smaller' larger) => proxy ns -> Many larger -> Many smaller' -> Many (ReplacesIndex ns smaller' larger)
+ Data.Diverse.Many: amendN' :: forall ns smaller smaller' larger proxy zipped. (AmendN' ns smaller smaller' larger zipped) => proxy ns -> Many larger -> Many smaller' -> Many (ReplacesIndex ns smaller' larger)
- Data.Diverse.Many: collect :: Many xs -> c xs r -> Collector (Via c) xs r
+ Data.Diverse.Many: collect :: Many xs -> c xs r -> Collector c xs r
- Data.Diverse.Many: collectN :: Many xs -> c n xs r -> CollectorN (ViaN c) n xs r
+ Data.Diverse.Many: collectN :: Many xs -> c n xs r -> CollectorN c n xs r
- Data.Diverse.Many: forMany :: c xs r -> Many xs -> Collector (Via c) xs r
+ Data.Diverse.Many: forMany :: c xs r -> Many xs -> Collector c xs r
- Data.Diverse.Many: forManyN :: c n xs r -> Many xs -> CollectorN (ViaN c) n xs r
+ Data.Diverse.Many: forManyN :: c n xs r -> Many xs -> CollectorN c n xs r
- Data.Diverse.Many: project' :: forall smaller smaller' larger. (Select smaller larger, Amend' smaller smaller' larger) => Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')
+ Data.Diverse.Many: project' :: forall smaller smaller' larger zipped. (Select smaller larger, Amend' smaller smaller' larger zipped) => Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')
- Data.Diverse.Many: projectN' :: forall ns smaller smaller' larger proxy. (SelectN ns smaller larger, AmendN' ns smaller smaller' larger) => proxy ns -> Lens (Many larger) (Many (ReplacesIndex ns smaller' larger)) (Many smaller) (Many smaller')
+ Data.Diverse.Many: projectN' :: forall ns smaller smaller' larger proxy zipped. (SelectN ns smaller larger, AmendN' ns smaller smaller' larger zipped) => proxy ns -> Lens (Many larger) (Many (ReplacesIndex ns smaller' larger)) (Many smaller) (Many smaller')
- Data.Diverse.Many: replace' :: forall x y xs. UniqueMember x xs => Proxy x -> Many xs -> y -> Many (Replace x y xs)
+ Data.Diverse.Many: replace' :: forall x y xs proxy. UniqueMember x xs => proxy x -> Many xs -> y -> Many (Replace x y xs)
- Data.Diverse.Many: type Amend smaller larger = (AFoldable (Collector (Via (CaseAmend larger)) smaller) (Key, WrappedAny), IsDistinct smaller)
+ Data.Diverse.Many: type Amend smaller larger = (AFoldable (CollectorAny (CaseAmend larger) smaller) (Int, WrappedAny), IsDistinct smaller)
- Data.Diverse.Many: type Amend' smaller smaller' larger = (AFoldable (Collector (Via (CaseAmend' larger)) (Zip smaller smaller')) (Key, WrappedAny), IsDistinct smaller)
+ Data.Diverse.Many: type Amend' smaller smaller' larger zipped = (AFoldable (CollectorAny (CaseAmend' larger) zipped) (Int, WrappedAny), IsDistinct smaller, zipped ~ Zip smaller smaller')
- Data.Diverse.Many: type AmendN ns smaller larger = (AFoldable (CollectorN (ViaN (CaseAmendN ns larger)) 0 smaller) (Key, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns)
+ Data.Diverse.Many: type AmendN ns smaller larger = (AFoldable (CollectorAnyN (CaseAmendN ns larger) 0 smaller) (Int, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns)
- Data.Diverse.Many: type AmendN' ns smaller smaller' larger = (AFoldable (CollectorN (ViaN (CaseAmendN' ns larger)) 0 (Zip smaller smaller')) (Key, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns)
+ Data.Diverse.Many: type AmendN' ns smaller smaller' larger zipped = (AFoldable (CollectorAnyN (CaseAmendN' ns larger) 0 zipped) (Int, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns, zipped ~ Zip smaller smaller')
- Data.Diverse.Many: type Select (smaller :: [Type]) (larger :: [Type]) = AFoldable (Collector (Via (CaseSelect smaller larger)) larger) [(Key, WrappedAny)]
+ Data.Diverse.Many: type Select (smaller :: [Type]) (larger :: [Type]) = AFoldable (CollectorAny (CaseSelect smaller larger) larger) (Maybe (Int, WrappedAny))
- Data.Diverse.Many: type SelectN (ns :: [Nat]) (smaller :: [Type]) (larger :: [Type]) = (AFoldable (CollectorN (ViaN (CaseSelectN ns smaller)) 0 larger) [(Key, WrappedAny)], smaller ~ KindsAtIndices ns larger, IsDistinct ns)
+ Data.Diverse.Many: type SelectN (ns :: [Nat]) (smaller :: [Type]) (larger :: [Type]) = (AFoldable (CollectorAnyN (CaseSelectN ns smaller) 0 larger) (Maybe (Int, WrappedAny)), smaller ~ KindsAtIndices ns larger, IsDistinct ns)
- Data.Diverse.Many.Internal: Many :: {-# UNPACK #-} !Int -> (Map Key Any) -> Many
+ Data.Diverse.Many.Internal: Many :: {-# UNPACK #-} !Int -> (Map Int Any) -> Many
- Data.Diverse.Many.Internal: amend' :: forall smaller smaller' larger. Amend' smaller smaller' larger => Proxy smaller -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger)
+ Data.Diverse.Many.Internal: amend' :: forall smaller smaller' larger proxy zipped. Amend' smaller smaller' larger zipped => proxy smaller -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger)
- Data.Diverse.Many.Internal: amendN' :: forall ns smaller smaller' larger proxy. (AmendN' ns smaller smaller' larger) => proxy ns -> Many larger -> Many smaller' -> Many (ReplacesIndex ns smaller' larger)
+ Data.Diverse.Many.Internal: amendN' :: forall ns smaller smaller' larger proxy zipped. (AmendN' ns smaller smaller' larger zipped) => proxy ns -> Many larger -> Many smaller' -> Many (ReplacesIndex ns smaller' larger)
- Data.Diverse.Many.Internal: collect :: Many xs -> c xs r -> Collector (Via c) xs r
+ Data.Diverse.Many.Internal: collect :: Many xs -> c xs r -> Collector c xs r
- Data.Diverse.Many.Internal: collectN :: Many xs -> c n xs r -> CollectorN (ViaN c) n xs r
+ Data.Diverse.Many.Internal: collectN :: Many xs -> c n xs r -> CollectorN c n xs r
- Data.Diverse.Many.Internal: forMany :: c xs r -> Many xs -> Collector (Via c) xs r
+ Data.Diverse.Many.Internal: forMany :: c xs r -> Many xs -> Collector c xs r
- Data.Diverse.Many.Internal: forManyN :: c n xs r -> Many xs -> CollectorN (ViaN c) n xs r
+ Data.Diverse.Many.Internal: forManyN :: c n xs r -> Many xs -> CollectorN c n xs r
- Data.Diverse.Many.Internal: project' :: forall smaller smaller' larger. (Select smaller larger, Amend' smaller smaller' larger) => Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')
+ Data.Diverse.Many.Internal: project' :: forall smaller smaller' larger zipped. (Select smaller larger, Amend' smaller smaller' larger zipped) => Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')
- Data.Diverse.Many.Internal: projectN' :: forall ns smaller smaller' larger proxy. (SelectN ns smaller larger, AmendN' ns smaller smaller' larger) => proxy ns -> Lens (Many larger) (Many (ReplacesIndex ns smaller' larger)) (Many smaller) (Many smaller')
+ Data.Diverse.Many.Internal: projectN' :: forall ns smaller smaller' larger proxy zipped. (SelectN ns smaller larger, AmendN' ns smaller smaller' larger zipped) => proxy ns -> Lens (Many larger) (Many (ReplacesIndex ns smaller' larger)) (Many smaller) (Many smaller')
- Data.Diverse.Many.Internal: replace' :: forall x y xs. UniqueMember x xs => Proxy x -> Many xs -> y -> Many (Replace x y xs)
+ Data.Diverse.Many.Internal: replace' :: forall x y xs proxy. UniqueMember x xs => proxy x -> Many xs -> y -> Many (Replace x y xs)
- Data.Diverse.Many.Internal: type Amend smaller larger = (AFoldable (Collector (Via (CaseAmend larger)) smaller) (Key, WrappedAny), IsDistinct smaller)
+ Data.Diverse.Many.Internal: type Amend smaller larger = (AFoldable (CollectorAny (CaseAmend larger) smaller) (Int, WrappedAny), IsDistinct smaller)
- Data.Diverse.Many.Internal: type Amend' smaller smaller' larger = (AFoldable (Collector (Via (CaseAmend' larger)) (Zip smaller smaller')) (Key, WrappedAny), IsDistinct smaller)
+ Data.Diverse.Many.Internal: type Amend' smaller smaller' larger zipped = (AFoldable (CollectorAny (CaseAmend' larger) zipped) (Int, WrappedAny), IsDistinct smaller, zipped ~ Zip smaller smaller')
- Data.Diverse.Many.Internal: type AmendN ns smaller larger = (AFoldable (CollectorN (ViaN (CaseAmendN ns larger)) 0 smaller) (Key, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns)
+ Data.Diverse.Many.Internal: type AmendN ns smaller larger = (AFoldable (CollectorAnyN (CaseAmendN ns larger) 0 smaller) (Int, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns)
- Data.Diverse.Many.Internal: type AmendN' ns smaller smaller' larger = (AFoldable (CollectorN (ViaN (CaseAmendN' ns larger)) 0 (Zip smaller smaller')) (Key, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns)
+ Data.Diverse.Many.Internal: type AmendN' ns smaller smaller' larger zipped = (AFoldable (CollectorAnyN (CaseAmendN' ns larger) 0 zipped) (Int, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns, zipped ~ Zip smaller smaller')
- Data.Diverse.Many.Internal: type Select (smaller :: [Type]) (larger :: [Type]) = AFoldable (Collector (Via (CaseSelect smaller larger)) larger) [(Key, WrappedAny)]
+ Data.Diverse.Many.Internal: type Select (smaller :: [Type]) (larger :: [Type]) = AFoldable (CollectorAny (CaseSelect smaller larger) larger) (Maybe (Int, WrappedAny))
- Data.Diverse.Many.Internal: type SelectN (ns :: [Nat]) (smaller :: [Type]) (larger :: [Type]) = (AFoldable (CollectorN (ViaN (CaseSelectN ns smaller)) 0 larger) [(Key, WrappedAny)], smaller ~ KindsAtIndices ns larger, IsDistinct ns)
+ Data.Diverse.Many.Internal: type SelectN (ns :: [Nat]) (smaller :: [Type]) (larger :: [Type]) = (AFoldable (CollectorAnyN (CaseSelectN ns smaller) 0 larger) (Maybe (Int, WrappedAny)), smaller ~ KindsAtIndices ns larger, IsDistinct ns)
- Data.Diverse.Type: type KindAtLabel (l :: k1) (xs :: [k2]) = KindAtLabelImpl l xs xs
+ Data.Diverse.Type: type KindAtLabel (l :: k1) (xs :: [k]) = KindAtLabelImpl l xs xs

Files

data-diverse.cabal view
@@ -1,5 +1,5 @@ name:                data-diverse-version:             0.3.0.0+version:             0.4.0.0 synopsis:            Extensible records and polymorphic variants. description:         "Data.Diverse.Many" is an extensible record for any size encoded efficiently as (Int, Map Int Any).                      "Data.Diverse.Which" is a polymorphic variant of possibilities encoded as (Int, Any).@@ -20,13 +20,11 @@  library   hs-source-dirs:      src-  exposed-modules:     Data.Diverse.AFoldable-                       Data.Diverse+  exposed-modules:     Data.Diverse+                       Data.Diverse.AFoldable                        Data.Diverse.Case                        Data.Diverse.Cases                        Data.Diverse.CaseTypeable-                       Data.Diverse.Collector-                       Data.Diverse.Emit                        Data.Diverse.Many                        Data.Diverse.Many.Internal                        Data.Diverse.Reduce
src/Data/Diverse.hs view
@@ -3,8 +3,6 @@     , module Data.Diverse.Case     , module Data.Diverse.Cases     , module Data.Diverse.CaseTypeable-    , module Data.Diverse.Collector-    , module Data.Diverse.Emit     , module Data.Diverse.Many     , module Data.Diverse.Reduce     , module Data.Diverse.Reiterate@@ -16,8 +14,6 @@ import Data.Diverse.Case import Data.Diverse.Cases import Data.Diverse.CaseTypeable-import Data.Diverse.Collector-import Data.Diverse.Emit import Data.Diverse.Many import Data.Diverse.Reduce import Data.Diverse.Reiterate
src/Data/Diverse/Case.hs view
@@ -8,8 +8,6 @@  import Data.Diverse.Type import Data.Kind-import GHC.Prim (Any)-import Unsafe.Coerce  -- | This class allows defining handlers that can handle the 'Head' type in the @xs@ typelist. -- In conjunction with 'Data.Diverse.Reiterate.Reiterate', you can define handlers that can handle all@@ -19,8 +17,3 @@ class Case c (xs :: [Type]) r where     -- | Return the handler/continuation when x is observed.     case' :: c xs r -> Head xs -> r-    case' c v = caseAny c (unsafeCoerce v)--    -- | A variation of 'case'' where x is left as 'Any'-    caseAny :: c xs r -> Any -> r-    caseAny c v = case' c (unsafeCoerce v)
− src/Data/Diverse/Collector.hs
@@ -1,86 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE UndecidableInstances #-}--module Data.Diverse.Collector where--import Data.Diverse.AFoldable-import Data.Diverse.Emit-import Data.Diverse.Reiterate-import Data.Kind-import GHC.TypeLits---- | Folds output from an 'Emit'ter of values while __'reiterate'__ing the @xs@ typelist.--- This guarantees that the @Emit e '[]@ is not instantiated.--- Undecidable instances! But this is safe since it's a wrapper-newtype Collector e (xs :: [Type]) r = Collector (e xs r)---- | null case that doesn't even use 'emit', so that an instance of @Emit e '[]@ is not needed.-instance AFoldable (Collector e '[]) r where-    afoldr _ z _ = z---- | Folds values by 'reiterate'ing 'Emit'ters through the @xs@ typelist.-instance ( Emit e (x ': xs) r-         , Reiterate e (x ': xs)-         , AFoldable (Collector e xs) r-         ) =>-         AFoldable (Collector e (x ': xs)) r where-    afoldr f z (Collector e) = f (emit e) (afoldr f z (Collector (reiterate e)))---- | A variation of 'Collector' which does require the @Emit e '[]@ instance for the empty typelist.--- Undecidable instances! But this is safe since it's a wrapper-newtype Collector0 e (xs :: [Type]) r = Collector0 (e xs r)---- | terminating case that does use @Emit e '[]@-instance (Emit e '[] r) =>-         AFoldable (Collector0 e '[]) r where-    afoldr f z (Collector0 e) = f (emit e) z---- | Folds values by 'reiterate'ing 'Emit'ters through the @xs@ typelist.-instance ( Emit e (x ': xs) r-         , Reiterate e (x ': xs)-         , AFoldable (Collector0 e xs) r-         ) =>-         AFoldable (Collector0 e (x ': xs)) r where-    afoldr f z (Collector0 e) = f (emit e) (afoldr f z (Collector0 (reiterate e)))-------------------------------------------------- | A variation of 'Collector' which __'reiterateN'__s the @xs@ typelist.--- This version guarantees that the @Emit (e n) '[]@ is not instantiated.--- Undecidable instances! But this is safe since it's a wrapper-newtype CollectorN e (n :: Nat) (xs :: [Type]) r = CollectorN (e n xs r)---- | null case that doesn't even use 'emit', so that an instance of @Emit (e n) '[]@ is not needed.-instance AFoldable (CollectorN e n '[]) r where-    afoldr _ z _ = z---- | Folds values by 'reiterateN'ing 'Emit'ters through the @xs@ typelist.-instance ( Emit (e n) (x ': xs) r-         , ReiterateN e n (x ': xs)-         , AFoldable (CollectorN e (n + 1) xs) r-         ) =>-         AFoldable (CollectorN e n (x ': xs)) r where-    afoldr f z (CollectorN e) = f (emit e) (afoldr f z (CollectorN (reiterateN e)))---- | A variation of 'Collector0' which __'reiterateN'__s the @xs@ typelist.--- Undecidable instances! But this is safe since it's a wrapper-newtype CollectorN0 e (n :: Nat) (xs :: [Type]) r = CollectorN0 (e n xs r)---- | terminating case that does use @Emit (e n) '[]@-instance (Emit (e n) '[] r) =>-         AFoldable (CollectorN0 e n '[]) r where-    afoldr f z (CollectorN0 e) = f (emit e) z---- | Folds values by 'reiterateN'ing 'Emit'ters through the @xs@ typelist.-instance ( Emit (e n) (x ': xs) r-         , ReiterateN e n (x ': xs)-         , AFoldable (CollectorN0 e (n + 1) xs) r-         ) =>-         AFoldable (CollectorN0 e n (x ': xs)) r where-    afoldr f z (CollectorN0 e) = f (emit e) (afoldr f z (CollectorN0 (reiterateN e)))
− src/Data/Diverse/Emit.hs
@@ -1,10 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PolyKinds #-}--module Data.Diverse.Emit where---- | 'Emit' can generate a value, and is differentiated with an additional @xs@ typelist-class Emit e (xs :: [k]) r where-    emit :: e xs r -> r
src/Data/Diverse/Many.hs view
@@ -11,7 +11,7 @@     , _Many'        -- * Construction-    , nul+    , nil     , single     , prefix     , (./)@@ -29,15 +29,20 @@     -- * Single field     -- ** Getter for single field     , fetch+    , fetchL     , fetchN     -- ** Setter for single field     , replace     , replace'+    , replaceL+    , replaceL'     , replaceN     , replaceN'     -- ** Lens for a single field     , item     , item'+    , itemL+    , itemL'     , itemN     , itemN' @@ -45,6 +50,7 @@     -- ** Getter for multiple fields     , Select     , select+    , selectL     , SelectN     , selectN     -- ** Setter for multiple fields@@ -52,6 +58,8 @@     , amend     , Amend'     , amend'+    , amendL+    , amendL'     , AmendN     , amendN     , AmendN'@@ -59,18 +67,16 @@     -- ** Lens for multiple fields     , project     , project'+    , projectL+    , projectL'     , projectN     , projectN'      -- * Destruction     -- ** By type-    , Via -- no constructor-    , via -- safe construction     , forMany     , collect     -- ** By Nat index offset-    , ViaN -- no constructor-    , viaN -- safe construction     , forManyN     , collectN     ) where
src/Data/Diverse/Many/Internal.hs view
@@ -3,7 +3,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE InstanceSigs #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-}@@ -28,7 +27,7 @@     , _Many'        -- * Construction-    , nul+    , nil     , single     , prefix     , (./)@@ -46,15 +45,20 @@     -- * Single field     -- ** Getter for single field     , fetch+    , fetchL     , fetchN     -- ** Setter for single field     , replace     , replace'+    , replaceL+    , replaceL'     , replaceN     , replaceN'     -- ** Lens for a single field     , item     , item'+    , itemL+    , itemL'     , itemN     , itemN' @@ -62,6 +66,7 @@     -- ** Getter for multiple fields     , Select     , select+    , selectL     , SelectN     , selectN     -- ** Setter for multiple fields@@ -69,6 +74,8 @@     , amend     , Amend'     , amend'+    , amendL+    , amendL'     , AmendN     , amendN     , AmendN'@@ -76,18 +83,16 @@     -- ** Lens for multiple fields     , project     , project'+    , projectL+    , projectL'     , projectN     , projectN'      -- * Destruction     -- ** By type-    , Via -- no constructor-    , via -- safe construction     , forMany     , collect     -- ** By Nat index offset-    , ViaN -- no constructor-    , viaN -- safe construction     , forManyN     , collectN     ) where@@ -97,8 +102,6 @@ import Data.Bool import Data.Diverse.AFoldable import Data.Diverse.Case-import Data.Diverse.Collector-import Data.Diverse.Emit import Data.Diverse.Reiterate import Data.Diverse.Type import Data.Kind@@ -118,12 +121,6 @@ -- These usages in this module are safe due to size guarantees provided by the typelist. import Prelude as Partial -newtype Key = Key Int deriving (Eq, Ord, Show)-newtype LeftOffset = LeftOffset Int-newtype LeftSize = LeftSize Int-newtype RightOffset = RightOffset Int-newtype NewRightOffset = NewRightOffset { unNewRightOffset :: Int }- -- | 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@@ -151,25 +148,44 @@ -- -- The constructor will guarantee the correct number and types of the elements. -- The constructor is only exported in the "Data.Diverse.Many.Internal" module-data Many (xs :: [Type]) = Many {-# UNPACK #-} !Int (M.Map Key Any)+data Many (xs :: [Type]) = Many {-# UNPACK #-} !Int (M.Map Int Any) --- | Inferred role is phantom which is incorrect+-- Inferred role is phantom which is incorrect+-- representational means:+-- @+-- Coercible '[Int] '[IntLike] => Coercible (Many '[Int]) (Many '[IntLike])+-- @ type role Many representational +-- | Many stored as a list. This is useful when folding over 'Many' efficienty+-- so that the conversion to List is only done once+data Many_ (xs :: [Type]) = Many_ [Any]++type role Many_ representational++toMany_ :: Many xs -> Many_ xs+toMany_ (Many _ m) = Many_ (snd <$> M.toAscList m)++fromMany_ :: Many_ xs -> Many xs+fromMany_ (Many_ xs) = Many 0 (M.fromList (zip [(0 :: Int)..] xs)) ----------------------------------------------------------------------- --- | A terminating 'G.Generic' instance encoded as a 'nul'.+-- | A terminating 'G.Generic' instance encoded as a 'nil'. instance G.Generic (Many '[]) where     type Rep (Many '[]) =  G.U1     from _ = {- G.U1 -} G.U1-    to G.U1 = nul+    to G.U1 = nil  -- | A 'G.Generic' instance encoded as the 'front' value 'G.:*:' with the 'aft' 'Many'. -- The 'G.C1' and 'G.S1' metadata are not encoded. instance G.Generic (Many (x ': xs)) where     type Rep (Many (x ': xs)) = (G.Rec0 x) G.:*: (G.Rec0 (Many xs))     from r = ({- G.Rec0 -} G.K1 (front r)) G.:*: ({- G.Rec0 -} G.K1 (aft r))+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE from #-}     to (({- G.Rec0 -} G.K1 a) G.:*: ({- G.Rec0 -} G.K1 b)) = a ./ b+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE to #-}  ----------------------------------------------------------------------- @@ -190,14 +206,16 @@ -- | @_Many = iso fromMany toMany@ _Many :: IsMany t xs a => Iso' (Many xs) (t xs a) _Many = iso fromMany toMany+{-# INLINE _Many #-}  -- | @_Many' = iso fromMany' toMany'@ _Many' :: IsMany Tagged xs a => Iso' (Many xs) a _Many' = iso fromMany' toMany'+{-# INLINE _Many' #-}  -- | These instances add about 7 seconds to the compile time! instance IsMany Tagged '[] () where-    toMany _ = nul+    toMany _ = nil     fromMany _ = Tagged ()  -- | This single field instance is the reason for 'Tagged' wrapper.@@ -207,72 +225,72 @@     fromMany r = Tagged (fetch @a r)  instance IsMany Tagged '[a,b] (a,b) where-    toMany (Tagged (a,b)) = a./b./nul+    toMany (Tagged (a,b)) = a./b./nil     fromMany r = Tagged (fetchN (Proxy @0) r, fetchN (Proxy @1) r)  instance IsMany Tagged '[a,b,c] (a,b,c) where-    toMany (Tagged (a,b,c)) = a./b./c./nul+    toMany (Tagged (a,b,c)) = a./b./c./nil     fromMany r = Tagged (fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r)  instance IsMany Tagged '[a,b,c,d] (a,b,c,d) where-    toMany (Tagged (a,b,c,d)) = a./b./c./d./nul+    toMany (Tagged (a,b,c,d)) = a./b./c./d./nil     fromMany r = Tagged (fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r)  instance IsMany Tagged '[a,b,c,d,e] (a,b,c,d,e) where-    toMany (Tagged (a,b,c,d,e)) = a./b./c./d./e./nul+    toMany (Tagged (a,b,c,d,e)) = a./b./c./d./e./nil     fromMany r = Tagged (fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r, fetchN (Proxy @4) r)  instance IsMany Tagged '[a,b,c,d,e,f] (a,b,c,d,e,f) where-    toMany (Tagged (a,b,c,d,e,f)) = a./b./c./d./e./f./nul+    toMany (Tagged (a,b,c,d,e,f)) = a./b./c./d./e./f./nil     fromMany r = Tagged ( fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r, fetchN (Proxy @4) r                         , fetchN (Proxy @5) r)  instance IsMany Tagged '[a,b,c,d,e,f,g] (a,b,c,d,e,f,g) where-    toMany (Tagged (a,b,c,d,e,f,g)) = a./b./c./d./e./f./g./nul+    toMany (Tagged (a,b,c,d,e,f,g)) = a./b./c./d./e./f./g./nil     fromMany r = Tagged ( fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r, fetchN (Proxy @4) r                         , fetchN (Proxy @5) r, fetchN (Proxy @6) r)  instance IsMany Tagged '[a,b,c,d,e,f,g,h] (a,b,c,d,e,f,g,h) where-    toMany (Tagged (a,b,c,d,e,f,g,h)) = a./b./c./d./e./f./g./h./nul+    toMany (Tagged (a,b,c,d,e,f,g,h)) = a./b./c./d./e./f./g./h./nil     fromMany r = Tagged ( fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r, fetchN (Proxy @4) r                         , fetchN (Proxy @5) r, fetchN (Proxy @6) r, fetchN (Proxy @7) r)  instance IsMany Tagged '[a,b,c,d,e,f,g,h,i] (a,b,c,d,e,f,g,h,i) where-    toMany (Tagged (a,b,c,d,e,f,g,h,i)) = a./b./c./d./e./f./g./h./i./ nul+    toMany (Tagged (a,b,c,d,e,f,g,h,i)) = a./b./c./d./e./f./g./h./i./ nil     fromMany r = Tagged ( fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r, fetchN (Proxy @4) r                         , fetchN (Proxy @5) r, fetchN (Proxy @6) r, fetchN (Proxy @7) r, fetchN (Proxy @8) r)  instance IsMany Tagged '[a,b,c,d,e,f,g,h,i,j] (a,b,c,d,e,f,g,h,i,j) where-    toMany (Tagged (a,b,c,d,e,f,g,h,i,j)) = a./b./c./d./e./f./g./h./i./j./nul+    toMany (Tagged (a,b,c,d,e,f,g,h,i,j)) = a./b./c./d./e./f./g./h./i./j./nil     fromMany r = Tagged ( fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r, fetchN (Proxy @4) r                         , fetchN (Proxy @5) r, fetchN (Proxy @6) r, fetchN (Proxy @7) r, fetchN (Proxy @8) r, fetchN (Proxy @9) r)  instance IsMany Tagged '[a,b,c,d,e,f,g,h,i,j,k] (a,b,c,d,e,f,g,h,i,j,k) where-    toMany (Tagged (a,b,c,d,e,f,g,h,i,j,k)) = a./b./c./d./e./f./g./h./i./j./k./nul+    toMany (Tagged (a,b,c,d,e,f,g,h,i,j,k)) = a./b./c./d./e./f./g./h./i./j./k./nil     fromMany r = Tagged ( fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r, fetchN (Proxy @4) r                         , fetchN (Proxy @5) r, fetchN (Proxy @6) r, fetchN (Proxy @7) r, fetchN (Proxy @8) r, fetchN (Proxy @9) r                         , fetchN (Proxy @10) r)  instance IsMany Tagged '[a,b,c,d,e,f,g,h,i,j,k,l] (a,b,c,d,e,f,g,h,i,j,k,l) where-    toMany (Tagged (a,b,c,d,e,f,g,h,i,j,k,l)) = a./b./c./d./e./f./g./h./i./j./k./l./nul+    toMany (Tagged (a,b,c,d,e,f,g,h,i,j,k,l)) = a./b./c./d./e./f./g./h./i./j./k./l./nil     fromMany r = Tagged ( fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r, fetchN (Proxy @4) r                         , fetchN (Proxy @5) r, fetchN (Proxy @6) r, fetchN (Proxy @7) r, fetchN (Proxy @8) r, fetchN (Proxy @9) r                         , fetchN (Proxy @10) r, fetchN (Proxy @11) r)  instance IsMany Tagged '[a,b,c,d,e,f,g,h,i,j,k,l,m] (a,b,c,d,e,f,g,h,i,j,k,l,m) where-    toMany (Tagged (a,b,c,d,e,f,g,h,i,j,k,l,m)) = a./b./c./d./e./f./g./h./i./j./k./l./m./nul+    toMany (Tagged (a,b,c,d,e,f,g,h,i,j,k,l,m)) = a./b./c./d./e./f./g./h./i./j./k./l./m./nil     fromMany r = Tagged ( fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r, fetchN (Proxy @4) r                         , fetchN (Proxy @5) r, fetchN (Proxy @6) r, fetchN (Proxy @7) r, fetchN (Proxy @8) r, fetchN (Proxy @9) r                         , fetchN (Proxy @10) r, fetchN (Proxy @11) r, fetchN (Proxy @12) r)  instance IsMany Tagged '[a,b,c,d,e,f,g,h,i,j,k,l,m,n] (a,b,c,d,e,f,g,h,i,j,k,l,m,n) where-    toMany (Tagged (a,b,c,d,e,f,g,h,i,j,k,l,m,n)) = a./b./c./d./e./f./g./h./i./j./k./l./m./n./nul+    toMany (Tagged (a,b,c,d,e,f,g,h,i,j,k,l,m,n)) = a./b./c./d./e./f./g./h./i./j./k./l./m./n./nil     fromMany r = Tagged ( fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r, fetchN (Proxy @4) r                         , fetchN (Proxy @5) r, fetchN (Proxy @6) r, fetchN (Proxy @7) r, fetchN (Proxy @8) r, fetchN (Proxy @9) r                         , fetchN (Proxy @10) r, fetchN (Proxy @11) r, fetchN (Proxy @12) r, fetchN (Proxy @13) r)  instance IsMany Tagged '[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o] (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) where-    toMany (Tagged (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)) = a./b./c./d./e./f./g./h./i./j./k./l./m./n./o./nul+    toMany (Tagged (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)) = a./b./c./d./e./f./g./h./i./j./k./l./m./n./o./nil     fromMany r = Tagged ( fetchN (Proxy @0) r, fetchN (Proxy @1) r, fetchN (Proxy @2) r, fetchN (Proxy @3) r, fetchN (Proxy @4) r                         , fetchN (Proxy @5) r, fetchN (Proxy @6) r, fetchN (Proxy @7) r, fetchN (Proxy @8) r, fetchN (Proxy @9) r                         , fetchN (Proxy @10) r, fetchN (Proxy @11) r, fetchN (Proxy @12) r, fetchN (Proxy @13) r, fetchN (Proxy @14) r)@@ -288,16 +306,17 @@ -- So we need to adjust the existing index on the RightMap by -- \OldRightKey -> RightIndex + LeftOffset + LeftSize (as above) -- \OldRightKey -> OldRightKey - RightOffset + LeftOffset + LeftSize-rightKeyForSnoc :: LeftOffset -> LeftSize -> RightOffset -> Key -> Key-rightKeyForSnoc (LeftOffset lo) (LeftSize ld) (RightOffset ro) (Key rk) =-    Key (rk - ro + lo + ld)+rightKeyForSnoc :: Int -> Int -> Int -> Int -> Int+rightKeyForSnoc lo ld ro rk = rk - ro + lo + ld+{-# INLINE rightKeyForSnoc #-}  -- | When appending two maps together, get the function to modify the RightMap's offset -- when adding LeftMap into RightMap. -- The existing contents of RightMap will not be changed. -- NewRightOffset = OldRightOffset - LeftSize-rightOffsetForCons :: LeftSize -> RightOffset -> NewRightOffset-rightOffsetForCons (LeftSize ld) (RightOffset ro) = NewRightOffset (ro - ld)+rightOffsetForCons :: Int -> Int -> Int+rightOffsetForCons ld ro = ro - ld+{-# INLINE rightOffsetForCons #-}  -- | When appending two maps together, get the function to 'M.mapKeys' the LeftMap -- when adding LeftMap into RightMap.@@ -308,30 +327,33 @@ -- So we need to adjust the existing index on the LeftMap by -- \OldLeftKey -> LeftIndex + NewRightOffset (as above) -- \OldLeftKey -> OldLeftKey - LeftOffset + NewRightOffset (as above)-leftKeyForCons :: LeftOffset -> NewRightOffset -> Key -> Key-leftKeyForCons (LeftOffset lo) (NewRightOffset ro) (Key lk) = Key (lk - lo + ro)+leftKeyForCons :: Int -> Int -> Int -> Int+leftKeyForCons lo ro lk = lk - lo + ro+{-# INLINE leftKeyForCons #-} --- | Analogous to 'Prelude.null'. Named 'nul' to avoid conflicting with 'Prelude.null'.-nul :: Many '[]-nul = Many 0 M.empty-infixr 5 `nul` -- to be the same as 'prefix'+-- | Analogous to 'Prelude.nill'. Named 'nil' to avoid conflicting with 'Prelude.nill'.+nil :: Many '[]+nil = Many 0 M.empty  -- | Create a Many from a single value. Analogous to 'M.singleton' single :: x -> Many '[x]-single v = Many 0 (M.singleton (Key 0) (unsafeCoerce v))+single v = Many 0 (M.singleton 0 (unsafeCoerce v))  -- | Add an element to the left of a Many. -- Not named @cons@ to avoid conflict with 'Control.Lens.cons' prefix :: x -> Many xs -> Many (x ': xs)-prefix x (Many ro rm) = Many (unNewRightOffset nro)+prefix x (Many ro rm) = Many nro     (M.insert-        (leftKeyForCons (LeftOffset 0) nro (Key 0))+        (leftKeyForCons 0 nro 0)         (unsafeCoerce x)         rm)   where-    nro = rightOffsetForCons (LeftSize 1) (RightOffset ro)+    nro = rightOffsetForCons 1 ro infixr 5 `prefix` +prefix' :: x -> Many_ xs -> Many_ (x ': xs)+prefix' x (Many_ xs) = Many_ (unsafeCoerce x : xs)+ -- | Infix version of 'prefix'. -- -- Mnemonic: Element on the left is smaller './' than the larger 'Many' to the right.@@ -343,7 +365,7 @@ -- Not named 'snoc' to avoid conflict with 'Control.Lens.snoc' postfix :: Many xs -> y -> Many (Append xs '[y]) postfix (Many lo lm) y = Many lo-    (M.insert (rightKeyForSnoc (LeftOffset lo) (LeftSize (M.size lm)) (RightOffset 0) (Key 0))+    (M.insert (rightKeyForSnoc lo (M.size lm) 0 0)         (unsafeCoerce y)         lm) infixl 5 `postfix`@@ -363,14 +385,14 @@ append (Many lo lm) (Many ro rm) = if ld >= rd     then Many          lo-         (lm `M.union` (M.mapKeys (rightKeyForSnoc (LeftOffset lo) (LeftSize ld) (RightOffset ro)) rm))+         (lm `M.union` (M.mapKeys (rightKeyForSnoc lo ld ro) rm))     else Many-         (unNewRightOffset nro)-         ((M.mapKeys (leftKeyForCons (LeftOffset lo) nro) lm) `M.union` rm)+         nro+         ((M.mapKeys (leftKeyForCons lo nro) lm) `M.union` rm)   where     ld = M.size lm     rd = M.size rm-    nro = rightOffsetForCons (LeftSize ld) (RightOffset ro)+    nro = rightOffsetForCons ld ro infixr 5 `append` -- like Data.List (++)  -----------------------------------------------------------------------@@ -380,6 +402,9 @@ front :: Many (x ': xs) -> x front (Many _ m) = unsafeCoerce (snd . Partial.head $ M.toAscList m) +front' :: Many_ (x ': xs) -> x+front' (Many_ xs) = unsafeCoerce (Partial.head xs)+ -- | Extract the 'back' element of a Many, which guaranteed to be non-empty. -- Analogous to 'Prelude.last' back :: Many (x ': xs) -> Last (x ': xs)@@ -388,32 +413,54 @@ -- | Extract the elements after the front of a Many, which guaranteed to be non-empty. -- Analogous to 'Partial.tail' aft :: Many (x ': xs) -> Many xs-aft (Many o m) = Many (o + 1) (M.delete (Key o) m)+aft (Many o m) = Many (o + 1) (M.delete o m) +aft' :: Many_ (x ': xs) -> Many_ xs+aft' (Many_ xs) = Many_ (Partial.tail xs)+ -- | Return all the elements of a Many except the 'back' one, which guaranteed to be non-empty. -- Analogous to 'Prelude.init' fore :: Many (x ': xs) -> Many (Init (x ': xs))-fore (Many o m) = Many o (M.delete (Key (o + M.size m - 1)) m)+fore (Many o m) = Many o (M.delete (o + M.size m - 1) m)  --------------------------------------------------  -- | Getter by unique type. Get the field with type @x@. -- -- @--- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nul'+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil' -- 'fetch' \@Int x \`shouldBe` 5 -- @ fetch :: forall x xs. UniqueMember x xs => Many xs -> x-fetch (Many o m) = unsafeCoerce (m M.! (Key (o + i)))-  where i = fromInteger (natVal @(IndexOf x xs) Proxy)+fetch = fetch_ +fetch_ :: forall x xs n. (KnownNat n, n ~ IndexOf x xs) => Many xs -> x+fetch_ (Many o m) = unsafeCoerce (m M.! (o + i))+  where i = fromInteger (natVal @n Proxy)+ -------------------------------------------------- +-- | 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'+-- 'fetchL' \@Foo Proxy y \`shouldBe` Tagged \@Foo \'X'+-- 'fetchL' \@"Hi" Proxy y \`shouldBe` Tagged \@"Hi" True+-- @+fetchL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> x+fetchL _ = fetch_ @x++--------------------------------------------------+ -- | Getter by index. Get the value of the field at index type-level Nat @n@ ----- @getchN (Proxy \@2) t@+-- @+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil'+-- 'fetchN' @1 Proxy x \`shouldBe` False+-- @ fetchN :: forall n x xs proxy. MemberAt n x xs => proxy n -> Many xs -> x-fetchN p (Many o m) = unsafeCoerce (m M.! (Key (o + i)))+fetchN p (Many o m) = unsafeCoerce (m M.! (o + i))   where i = fromInteger (natVal p)  --------------------------------------------------@@ -421,38 +468,70 @@ -- | 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'+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil'+-- 'replace' \@Int x 6 \`shouldBe` (6 :: Int) './' False './' \'X' './' Just \'O' './' 'nil' -- @ replace :: forall x xs. UniqueMember x xs => Many xs -> x -> Many xs-replace (Many o m) v = Many o (M.insert (Key (o + i)) (unsafeCoerce v) m)-  where i = fromInteger (natVal @(IndexOf x xs) Proxy)+replace = replace_ +replace_ :: forall x xs n. (KnownNat n, n ~ IndexOf x xs) => Many xs -> x -> Many xs+replace_ (Many o m) v = Many o (M.insert (o + i) (unsafeCoerce v) m)+  where i = fromInteger (natVal @n Proxy)+ -- | Polymorphic setter by unique type. Set the field with type @x@, and replace with type @y@ -- -- @--- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nul'--- 'replace'' \@Int Proxy x (Just True) \`shouldBe` Just True './' False './' \'X' './' Just \'O' './' 'nul'+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil'+-- 'replace'' \@Int Proxy x (Just True) \`shouldBe` Just True './' False './' \'X' './' Just \'O' './' 'nil' -- @-replace' :: forall x y xs. UniqueMember x xs => Proxy x -> Many xs -> y -> Many (Replace x y xs)-replace' _ (Many o m) v = Many o (M.insert (Key (o + i)) (unsafeCoerce v) m)-  where i = fromInteger (natVal @(IndexOf x xs) Proxy)+replace' :: forall x y xs proxy. UniqueMember x xs => proxy x -> Many xs -> y -> Many (Replace x y xs)+replace' = replace'_ +replace'_ :: forall x y xs n proxy. (KnownNat n, n ~ IndexOf x xs) => proxy x -> Many xs -> y -> Many (Replace x y xs)+replace'_ _ (Many o m) v = Many o (M.insert (o + i) (unsafeCoerce v) m)+  where i = fromInteger (natVal @n Proxy)+ -------------------------------------------------- +-- | 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 Proxy y (Tagged \@Foo \'Y') \`shouldBe`+--     (5 :: Int) './' False './' Tagged \@Foo \'Y' './' Tagged \@\"Hello" (6 :: Int) './' 'nil'+-- 'replaceL' \@\"Hello" Proxy y (Tagged \@\"Hello" 7) \`shouldBe`+--     (5 :: Int) './' False './' Tagged \@Foo \'X' './' Tagged \@\"Hello" (7 :: Int) './' 'nil'+-- @+replaceL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> x -> Many xs+replaceL _ = replace_ @x++-- | 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 Proxy y (Tagged \@Bar \'Y') `shouldBe`+--     (5 :: Int) './' False './' Tagged @Bar 'Y' './' Tagged @"Hello" (6 :: Int) './' 'nil'+-- replaceL' \@\"Hello" Proxy y (Tagged \@\"Hello" False) \`shouldBe`+--     (5 :: Int) './' False './' Tagged \@Foo \'X' './' Tagged \@\"Hello" False './' 'nil'+-- @+replaceL' :: forall l y xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> y -> Many (Replace x y xs)+replaceL' _ = replace'_ @x Proxy++--------------------------------------------------+ -- | Setter by index. Set the value of the field at index type-level Nat @n@ -- -- @--- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nul'+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil' -- 'replaceN' \@0 Proxy x 7 `shouldBe` -- @ replaceN :: forall n x y xs proxy. MemberAt n x xs => proxy n -> Many xs -> y -> Many xs-replaceN p (Many o m) v = Many o (M.insert (Key (o + i)) (unsafeCoerce v) m)+replaceN p (Many o m) v = Many o (M.insert (o + i) (unsafeCoerce v) m)   where i = fromInteger (natVal p)  -- | Polymorphic version of 'replaceN' replaceN' :: forall n x y xs proxy. MemberAt n x xs => proxy n -> Many xs -> y -> Many (ReplaceIndex n y xs)-replaceN' p (Many o m) v = Many o (M.insert (Key (o + i)) (unsafeCoerce v) m)+replaceN' p (Many o m) v = Many o (M.insert (o + i) (unsafeCoerce v) m)   where i = fromInteger (natVal p)  -----------------------------------------------------------------------@@ -460,9 +539,9 @@ -- | 'fetch' ('view' 'item') and 'replace' ('set' 'item') in 'Lens'' form. -- -- @--- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nul'+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil' -- x '^.' 'item' \@Int \`shouldBe` 5--- (x '&' 'item' \@Int .~ 6) \`shouldBe` (6 :: Int) './' False './' \'X' './' Just \'O' './' 'nul'+-- (x '&' 'item' \@Int .~ 6) \`shouldBe` (6 :: Int) './' False './' \'X' './' Just \'O' './' 'nil' -- @ item :: forall x xs. UniqueMember x xs => Lens' (Many xs) x item = lens fetch replace@@ -473,12 +552,35 @@ item' = lens fetch (replace' @x @y Proxy) {-# INLINE item' #-} ++-- | 'fetchL' ('view' 'itemL') and 'replaceL' ('set' 'itemL') in 'Lens'' form.+--+-- @+-- let x = (5 :: Int) './' Tagged \@Foo False './' Tagged \@Bar \'X' './' 'nil'+-- x '^.' 'itemL' \@Foo Proxy \`shouldBe` Tagged \@Foo False+-- (x '&' 'itemL' \@Foo Proxy '.~' Tagged \@Foo True) \`shouldBe` (5 :: Int) './' Tagged \@Foo True './' Tagged \@Bar \'X' './' 'nil'+-- @+itemL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Lens' (Many xs) x+itemL p = lens (fetchL p) (replaceL p)+{-# INLINE itemL #-}++-- | Polymorphic version of 'itemL'+--+-- @+-- let x = (5 :: Int) './' Tagged @Foo False './' Tagged \@Bar \'X' './' 'nil'+-- (x '&' itemL' \@Foo Proxy '.~' \"foo") \`shouldBe` (5 :: Int) './' \"foo" './' Tagged \@Bar \'X' './' 'nil'+-- @+itemL' :: forall l y xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Lens (Many xs) (Many (Replace x y xs)) x y+itemL' p = lens (fetchL p) (replaceL' p)+{-# INLINE itemL' #-}++ -- | 'fetchN' ('view' 'item') and 'replaceN' ('set' 'item') in 'Lens'' form. -- -- @--- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' ./ nul+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' ./ nil -- x '^.' 'itemN' (Proxy \@0) \`shouldBe` 5--- (x '&' 'itemN' (Proxy @0) '.~' 6) \`shouldBe` (6 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nul'+-- (x '&' 'itemN' (Proxy @0) '.~' 6) \`shouldBe` (6 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nil' -- @ itemN ::  forall n x xs proxy. MemberAt n x xs => proxy n -> Lens' (Many xs) x itemN p = lens (fetchN p) (replaceN p)@@ -498,27 +600,87 @@  ----------------------------------------------------------------------- --- | Wraps a 'Case' into an instance of 'Emit', 'reiterate'ing and feeding 'Case' with the value from the 'Many'--- and 'emit'ting the results.+class CaseAny c (xs :: [Type]) r where+    -- | Return the handler/continuation when x is observed.+    caseAny :: c xs r -> Any -> r++-----------------------------------------------------------------------++-- | Variation of 'Collector' which uses 'CaseAny' instead of 'Case'+data CollectorAny c (xs :: [Type]) r = CollectorAny (c xs r) [Any]++-- | nill case that doesn't even use 'caseAny', so that an instance of @CaseAny '[]@ is not needed.+instance AFoldable (CollectorAny c '[]) r where+    afoldr _ z _ = z++instance ( CaseAny c (x ': xs) r+         , Reiterate c (x ': xs)+         , AFoldable (CollectorAny c xs) r+         ) =>+         AFoldable (CollectorAny c (x ': xs)) r where+    afoldr f z (CollectorAny c xs) = f (caseAny c x) (afoldr f z (CollectorAny (reiterate c) xs'))+      where+       -- use of head/tail here is safe as we are guaranteed the length from the typelist+       x = Partial.head xs+       xs' = Partial.tail xs+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE afoldr #-}++forMany' :: c xs r -> Many xs -> CollectorAny c xs r+forMany' c (Many _ xs) = CollectorAny c (snd <$> M.toAscList xs)++-----------------------------------------------------------------------++-- | A variation of 'CollectorN' which uses 'CaseAny' instead of 'Case'+data CollectorAnyN c n (xs :: [Type]) r = CollectorAnyN (c n xs r) [Any]++-- | nill case that doesn't even use 'caseAnyN', so that an instance of @CaseAnyN '[]@ is not needed.+instance AFoldable (CollectorAnyN c n '[]) r where+    afoldr _ z _ = z++instance ( CaseAny (c n) (x ': xs) r+         , ReiterateN c n (x ': xs)+         , AFoldable (CollectorAnyN c (n + 1) xs) r+         ) =>+         AFoldable (CollectorAnyN c n (x ': xs)) r where+    afoldr f z (CollectorAnyN c xs) = f (caseAny c x) (afoldr f z (CollectorAnyN (reiterateN c) xs'))+      where+       -- use of head/tail here is safe as we are guaranteed the length from the typelist+       x = Partial.head xs+       xs' = Partial.tail xs+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE afoldr #-}++forManyN' :: c n xs r -> Many xs -> CollectorAnyN c n xs r+forManyN' c (Many _ xs) = CollectorAnyN c (snd <$> M.toAscList xs)++-----------------------------------------------------------------------++-- | 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@.+--  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@.-newtype Via c (xs :: [Type]) r = Via (c xs r, [Any])---- | Creates an 'Via' safely, so that the invariant of \"typelist to the value list type and size\" holds.-via :: c xs r -> Many xs -> Via c xs r-via c (Many _ m) = Via (c, snd <$> M.toAscList m)+-- 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@.+data Collector c (xs :: [Type]) r = Collector (c xs r) [Any] -instance Reiterate c (x ': xs) => Reiterate (Via c) (x ': xs) where-    -- use of tail here is safe as we are guaranteed the length from the typelist-    reiterate (Via (c, xxs)) = Via (reiterate c, Partial.tail xxs)+-- | nill case that doesn't even use 'case'', so that an instance of @Case '[]@ is not needed.+instance AFoldable (Collector c '[]) r where+    afoldr _ z _ = z -instance (Case c (x ': xs) r) => Emit (Via c) (x ': xs) r where-    emit (Via (c, xxs)) = caseAny c v+-- | Folds values by 'reiterate'ing 'Emit'ters through the @xs@ typelist.+instance ( Case c (x ': xs) r+         , Reiterate c (x ': xs)+         , AFoldable (Collector c xs) r+         ) =>+         AFoldable (Collector c (x ': xs)) r where+    afoldr f z (Collector c xs) = f (case' c v) (afoldr f z (Collector (reiterate c) xs'))       where-       -- use of front here is safe as we are guaranteed the length from the typelist-       v = Partial.head xxs+       -- use of head/tail here is safe as we are guaranteed the length from the typelist+       v = unsafeCoerce $ Partial.head xs+       xs' = Partial.tail xs+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE afoldr #-}  ----------------------------------------------------------------------- @@ -529,43 +691,47 @@ -- 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'+-- 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' ('Data.Diverse.Cases.cases' y) x) \`shouldBe` --     [\"5", \"False", \"\'X'", \"Just \'O'", \"6", \"Just \'A'"] -- @-forMany :: c xs r -> Many xs -> Collector (Via c) xs r-forMany c x = Collector (via c x)+forMany :: c xs r -> Many xs -> Collector c xs r+forMany c (Many _ xs) = Collector c (snd <$> M.toAscList xs)  -- | 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'+-- 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 ('Data.Diverse.Cases.cases' y)) \`shouldBe` --     [\"5", \"False", \"\'X'", \"Just \'O'", \"6", \"Just \'A'"] -- @-collect :: Many xs -> c xs r -> Collector (Via c) xs r+collect :: Many xs -> c xs r -> Collector c xs r collect = flip forMany  ----------------------------------------------------------------------- --- | A variation of 'Via' which __'reiterateN'__ instead.-newtype ViaN c (n :: Nat) (xs :: [Type]) r = ViaN (c n xs r, [Any])---- | Creates an 'ViaN' safely, so that the invariant of \"typelist to the value list type and size\" holds.-viaN :: c n xs r -> Many xs -> ViaN c n xs r-viaN c (Many _ m) = ViaN (c, snd <$> M.toAscList m)+-- | A variation of 'Collector' which uses 'ReiterateN' instead of 'Reiterate'+data CollectorN c (n :: Nat) (xs :: [Type]) r = CollectorN (c n xs r) [Any] -instance ReiterateN c n (x ': xs) => ReiterateN (ViaN c) n (x ': xs) where-    -- use of tail here is safe as we are guaranteed the length from the typelist-    reiterateN (ViaN (c, xxs)) = ViaN (reiterateN c, Partial.tail xxs)+-- | nill case that doesn't even use 'case'', so that an instance of @Case '[]@ is not needed.+instance AFoldable (CollectorN c n '[]) r where+    afoldr _ z _ = z -instance (Case (c n) (x ': xs) r) => Emit (ViaN c n) (x ': xs) r where-    emit (ViaN (c, xxs)) = caseAny c v+-- | Folds values by 'reiterate'ing 'Emit'ters through the @xs@ typelist.+instance ( Case (c n) (x ': xs) r+         , ReiterateN c n (x ': xs)+         , AFoldable (CollectorN c (n + 1) xs) r+         ) =>+         AFoldable (CollectorN c n (x ': xs)) r where+    afoldr f z (CollectorN c xs) = f (case' c v) (afoldr f z (CollectorN (reiterateN c) xs'))       where-       -- use of front here is safe as we are guaranteed the length from the typelist-       v = Partial.head xxs+       -- use of head/tail here is safe as we are guaranteed the length from the typelist+       v = unsafeCoerce $ Partial.head xs+       xs' = Partial.tail xs+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE afoldr #-}  -- | Folds any 'Many', even with indistinct types. -- Given __index__ handlers for the fields in 'Many', create a 'CollectorN'@@ -574,23 +740,23 @@ -- 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'+-- 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' ('Data.Diverse.Cases.casesN' y) x) \`shouldBe` --     [\"5", \"False", \"\'X'", \"Just \'O'", \"6", \"Just \'A'"] -- @-forManyN :: c n xs r -> Many xs -> CollectorN (ViaN c) n xs r-forManyN c x = CollectorN (viaN c x)+forManyN :: c n xs r -> Many xs -> CollectorN c n xs r+forManyN c (Many _ xs) = CollectorN c (snd <$> M.toAscList xs)  -- | 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'+-- 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 ('Data.Diverse.Cases.casesN' y)) \`shouldBe` --     [\"5", \"False", \"\'X'", \"Just \'O'", \"6", \"Just \'A'"] -- @-collectN :: Many xs -> c n xs r -> CollectorN (ViaN c) n xs r+collectN :: Many xs -> c n xs r -> CollectorN c n xs r collectN = flip forManyN  -----------------------------------------------------------------------@@ -598,7 +764,7 @@ -- | A friendlier type constraint synomyn for 'select' type Select (smaller :: [Type]) (larger :: [Type]) =     (AFoldable-        ( Collector (Via (CaseSelect smaller larger)) larger) [(Key, WrappedAny)])+        ( CollectorAny (CaseSelect smaller larger) larger) (Maybe (Int, WrappedAny)))  -- | Construct a 'Many' with a smaller number of fields than the original. -- Analogous to 'fetch' getter but for multiple fields.@@ -606,35 +772,53 @@ -- 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'--- 'select' \@'[Bool, Char] x \`shouldBe` False './' \'X' './' 'nul'+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nil'+-- 'select' \@'[Bool, Char] x \`shouldBe` False './' \'X' './' 'nil' -- @ select :: forall smaller larger. Select smaller larger => Many larger -> Many smaller select t = Many 0 (fromList' xs')   where-    xs' = afoldr (++) [] (Collector (via (CaseSelect @smaller @larger @larger) t))+    xs' = afoldr (\a z -> maybe z (: z) a) [] (forMany' (CaseSelect @smaller @larger @larger) t)  -- | For each type x in @larger@, generate the (k, v) in @smaller@ (if it exists) data CaseSelect (smaller :: [Type]) (larger :: [Type]) (xs :: [Type]) r = CaseSelect  instance Reiterate (CaseSelect smaller larger) (x ': xs) where-    reiterate CaseSelect = CaseSelect+    reiterate = coerce --- | For each type x in larger, find the index in ys, and create an (incrementing key, value)-instance forall smaller larger x xs. (UniqueIfExists smaller x larger, MaybeUniqueMember x smaller) =>-         Case (CaseSelect smaller larger) (x ': xs) [(Key, WrappedAny)] where+-- | For each type x in larger, find the index in ys, and create a (key, value)+instance forall smaller larger x xs n. (UniqueIfExists smaller x larger, MaybeUniqueMemberAt n x smaller) =>+         CaseAny (CaseSelect smaller larger) (x ': xs) (Maybe (Int, WrappedAny)) where     caseAny _ v =         case i of-            0 -> []-            i' -> [(Key (i' - 1), WrappedAny v)]+            0 -> Nothing+            i' -> Just (i' - 1, WrappedAny v)       where-        i = fromInteger (natVal @(PositionOf x smaller) Proxy)+        i = fromInteger (natVal @n Proxy)  ----------------------------------------------------------------------- +-- | 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] Proxy x \`shouldBe` Tagged \@Foo False './' Tagged \@Bar \'X' './' 'nil'+-- 'selectL' \@'[\"Hi", \"Bye"] Proxy x \`shouldBe` Tagged \@\"Hi" (5 :: Int) './' Tagged \@\"Bye" \'O' './' 'nil'+-- @+selectL+    :: forall ls smaller larger proxy.+       ( Select smaller larger+       , smaller ~ KindsAtLabels ls larger+       , IsDistinct ls+       , UniqueLabels ls larger)+    => proxy ls -> Many larger -> Many smaller+selectL _ = select @smaller++-----------------------------------------------------------------------+ -- | A friendlier type constraint synomyn for 'selectN' type SelectN (ns :: [Nat]) (smaller ::[Type]) (larger :: [Type]) =-    ( AFoldable (CollectorN (ViaN (CaseSelectN ns smaller)) 0 larger) [(Key, WrappedAny)]+    ( AFoldable (CollectorAnyN (CaseSelectN ns smaller) 0 larger) (Maybe (Int, WrappedAny))     , smaller ~ KindsAtIndices ns larger     , IsDistinct ns) @@ -648,8 +832,8 @@ -- the mapping is specified by @indicies@. -- -- @--- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nul'--- 'selectN' (Proxy @'[5, 4, 0]) x \`shouldBe` Just \'A' './' (6 :: Int) './' (5 ::Int) './' 'nul'+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nil'+-- 'selectN' (Proxy @'[5, 4, 0]) x \`shouldBe` Just \'A' './' (6 :: Int) './' (5 ::Int) './' 'nil' -- @ selectN     :: forall ns smaller larger proxy.@@ -657,7 +841,7 @@     => proxy ns -> Many larger -> Many smaller selectN _ xs = Many 0 (fromList' xs')   where-    xs' = afoldr (++) [] (forManyN (CaseSelectN @ns @smaller @0 @larger) xs)+    xs' = afoldr (\a z -> maybe z (: z) a) [] (forManyN' (CaseSelectN @ns @smaller @0 @larger) xs)  data CaseSelectN (indices :: [Nat]) (smaller :: [Type]) (n :: Nat) (xs :: [Type]) r = CaseSelectN @@ -665,76 +849,121 @@     reiterateN CaseSelectN = CaseSelectN  -- | For each type x in @larger@, find the index in ys, and create an (incrementing key, value)-instance forall indices smaller n x xs. MaybeMemberAt (PositionOf n indices) x smaller =>-         Case (CaseSelectN indices smaller n) (x ': xs) [(Key, WrappedAny)] where+instance forall indices smaller n x xs n'. (MaybeMemberAt n' x smaller, n' ~ PositionOf n indices) =>+         CaseAny (CaseSelectN indices smaller n) (x ': xs) (Maybe (Int, WrappedAny)) where     caseAny _ v =         case i of-            0 -> []-            i' -> [(Key (i' - 1), WrappedAny v)]+            0 -> Nothing+            i' -> Just (i' - 1, WrappedAny v)       where-        i = fromInteger (natVal @(PositionOf n indices) Proxy)+        i = fromInteger (natVal @n' Proxy)  -----------------------------------------------------------------------  -- | A friendlier type constraint synomyn for 'amend'-type Amend smaller larger = (AFoldable (Collector (Via (CaseAmend larger)) smaller) (Key, WrappedAny)+type Amend smaller larger = (AFoldable (CollectorAny (CaseAmend larger) smaller) (Int, WrappedAny)        , IsDistinct smaller)  -- | 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'+-- 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' -- @ amend :: forall smaller larger. Amend smaller larger => Many larger -> Many smaller -> Many larger amend (Many lo lm) t = Many lo (fromList' xs' `M.union` lm)   where-    xs' = afoldr (:) [] (forMany (CaseAmend @larger @smaller lo) t)+    xs' = afoldr (:) [] (forMany' (CaseAmend @larger @smaller lo) t)  newtype CaseAmend (larger :: [Type]) (xs :: [Type]) r = CaseAmend Int  instance Reiterate (CaseAmend larger) (x ': xs) where-    reiterate (CaseAmend lo) = CaseAmend lo+    reiterate = coerce  -- | for each x in @smaller@, convert it to a (k, v) to insert into the x in @Many larger@-instance UniqueMember x larger => Case (CaseAmend larger) (x ': xs) (Key, WrappedAny) where-    caseAny (CaseAmend lo) v = (Key (lo + i), WrappedAny v)+instance UniqueMemberAt n x larger => CaseAny (CaseAmend larger) (x ': xs) (Int, WrappedAny) where+    caseAny (CaseAmend lo) v = (lo + i, WrappedAny v)       where-        i = fromInteger (natVal @(IndexOf x larger) Proxy)+        i = fromInteger (natVal @n Proxy)  ----------------------------------------------------------------------- +-- | 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] Proxy 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"] Proxy 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'+-- @+amendL+    :: forall ls smaller larger proxy.+       ( Amend smaller larger+       , smaller ~ KindsAtLabels ls larger+       , IsDistinct ls+       , UniqueLabels ls larger)+    => proxy ls -> Many larger -> Many smaller -> Many larger+amendL _ = amend @(KindsAtLabels ls larger)++-----------------------------------------------------------------------+ -- | A friendlier type constraint synomyn for 'amend''-type Amend' smaller smaller' larger = (AFoldable (Collector (Via (CaseAmend' larger)) (Zip smaller smaller')) (Key, WrappedAny), IsDistinct smaller)+type Amend' smaller smaller' larger zipped =+    ( AFoldable (CollectorAny (CaseAmend' larger) zipped) (Int, WrappedAny)+    , IsDistinct smaller+    , zipped ~ Zip smaller smaller') -amend' :: forall smaller smaller' larger. Amend' smaller smaller' larger-    => Proxy smaller -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger)+amend' :: forall smaller smaller' larger proxy zipped. Amend' smaller smaller' larger zipped+    => proxy smaller -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger) amend' _ (Many lo lm) t = Many lo (fromList' xs' `M.union` lm)   where-    xs' = afoldr (:) [] (Collector (via' @smaller Proxy (CaseAmend' @larger @(Zip smaller smaller') lo) t))+    xs' = afoldr (:) [] (forMany'' @smaller Proxy (CaseAmend' @larger @zipped lo) t) --- | We are cheating here and saying that the @y@ can be unsafeCoerced into a type of @(x, y)@--- but we only every coerce from 'Any' back into @y@in the @caseAny (CaseAmend' lo) v@ below.-via' :: Proxy xs -> c (Zip xs ys) r -> Many ys -> Via c (Zip xs ys) r-via' _ c (Many _ m) = Via (c, snd <$> M.toAscList m)+forMany'' :: Proxy xs -> c (Zip xs ys) r -> Many ys -> CollectorAny c (Zip xs ys) r+forMany'' _ c (Many _ ys) = CollectorAny c (snd <$> M.toAscList ys)  newtype CaseAmend' (larger :: [Type]) (zs :: [Type]) r = CaseAmend' Int  instance Reiterate (CaseAmend' larger) (z ': zs) where-    reiterate (CaseAmend' lo) = CaseAmend' lo+    reiterate = coerce  -- | for each y in @smaller@, convert it to a (k, v) to insert into the x in @Many larger@-instance UniqueMember x larger => Case (CaseAmend' larger) ((x, y) ': zs) (Key, WrappedAny) where-    caseAny (CaseAmend' lo) v = (Key (lo + i), WrappedAny v)+instance (UniqueMemberAt n x larger) => CaseAny (CaseAmend' larger) ((x, y) ': zs) (Int, WrappedAny) where+    caseAny (CaseAmend' lo) v = (lo + i, WrappedAny v)       where-        i = fromInteger (natVal @(IndexOf x larger) Proxy)+        i = fromInteger (natVal @n Proxy)  -----------------------------------------------------------------------++-- | 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] Proxy x (\'Y' './' True './' 'ni'l) \`shouldBe`+--     False './' Tagged \@\"Hi" (5 :: Int) './' \'Y' './' True './' Tagged \@\"Bye" \'O' './' 'nil'+-- 'amendL'' \@'[\"Hi", \"Bye"] Proxy x (True './' Tagged \@\"Changed" True './' 'nil') \`shouldBe`+--     False './' True './' Tagged \@Foo False './' Tagged \@Bar \'X' './' Tagged \@\"Changed" True './' 'nil'+-- @+amendL'+    :: forall ls smaller smaller' larger proxy zipped.+       ( Amend' smaller smaller' larger zipped+       , smaller ~ KindsAtLabels ls larger+       , IsDistinct ls+       , UniqueLabels ls larger+       )+    => proxy ls+    -> Many larger+    -> Many smaller'+    -> Many (Replaces smaller smaller' larger)+amendL' _ = amend' @(KindsAtLabels ls larger) Proxy++----------------------------------------------------------------------- -- | A friendlier type constraint synomyn for 'amendN' type AmendN ns smaller larger =-    ( AFoldable (CollectorN (ViaN (CaseAmendN ns larger)) 0 smaller) (Key, WrappedAny)+    ( AFoldable (CollectorAnyN (CaseAmendN ns larger) 0 smaller) (Int, WrappedAny)     , smaller ~ KindsAtIndices ns larger     , IsDistinct ns) @@ -748,61 +977,60 @@ -- 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'+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nil'+-- 'amendN' (Proxy \@'[5, 4, 0]) x (Just \'B' './' (8 :: Int) './' (4 ::Int) './' 'nil') \`shouldBe`+--     (4 :: Int) './' False './' \'X' './' Just \'O' './' (8 :: Int) './' Just \'B' './' 'nil' -- @ amendN :: forall ns smaller larger proxy.        (AmendN ns smaller larger)     => proxy ns -> Many larger -> Many smaller -> Many larger amendN _ (Many lo lm) t = Many lo (fromList' xs' `M.union` lm)   where-    xs' = afoldr (:) [] (forManyN (CaseAmendN @ns @larger @0 @smaller lo) t)-------------------------------------------------------------------------+    xs' = afoldr (:) [] (forManyN' (CaseAmendN @ns @larger @0 @smaller lo) t)  newtype CaseAmendN (indices :: [Nat]) (larger :: [Type]) (n :: Nat) (xs :: [Type]) r = CaseAmendN Int  instance ReiterateN (CaseAmendN indices larger) n (x ': xs) where-    reiterateN (CaseAmendN lo) = CaseAmendN lo+    reiterateN = coerce  -- | for each x in @smaller@, convert it to a (k, v) to insert into the x in @larger@-instance (MemberAt (KindAtIndex n indices) x larger) =>-         Case (CaseAmendN indices larger n) (x ': xs) (Key, WrappedAny) where-    caseAny (CaseAmendN lo) v = (Key (lo + i), WrappedAny v)+instance (MemberAt n' x larger, n' ~ KindAtIndex n indices) =>+         CaseAny (CaseAmendN indices larger n) (x ': xs) (Int, WrappedAny) where+    caseAny (CaseAmendN lo) v = (lo + i, WrappedAny v)       where-        i = fromInteger (natVal @(KindAtIndex n indices) Proxy)+        i = fromInteger (natVal @n' Proxy) +-----------------------------------------------------------------------+ -- | A friendlier type constraint synomyn for 'amendN'-type AmendN' ns smaller smaller' larger =-    ( AFoldable (CollectorN (ViaN (CaseAmendN' ns larger)) 0 (Zip smaller smaller')) (Key, WrappedAny)+type AmendN' ns smaller smaller' larger zipped =+    ( AFoldable (CollectorAnyN (CaseAmendN' ns larger) 0 zipped) (Int, WrappedAny)     , smaller ~ KindsAtIndices ns larger-    , IsDistinct ns)+    , IsDistinct ns+    , zipped ~ Zip smaller smaller')  -- | A polymorphic variation of 'amendN'-amendN' :: forall ns smaller smaller' larger proxy.-       (AmendN' ns smaller smaller' larger)+amendN' :: forall ns smaller smaller' larger proxy zipped.+       (AmendN' ns smaller smaller' larger zipped)     => proxy ns -> Many larger -> Many smaller' -> Many (ReplacesIndex ns smaller' larger) amendN' _ (Many lo lm) t = Many lo (fromList' xs' `M.union` lm)   where-    xs' = afoldr (:) [] (CollectorN (viaN' @smaller Proxy (CaseAmendN' @ns @larger @0 @(Zip smaller smaller') lo) t))+    xs' = afoldr (:) [] (forManyN'' @smaller Proxy (CaseAmendN' @ns @larger @0 @zipped lo) t) --- | We are cheating here and saying that the @y@ can be unsafeCoerced into a type of @(x, y)@--- but we only every coerce from 'Any' back into @y@in the @caseAny (CaseAmend' lo) v@ below.-viaN' :: Proxy xs -> c n (Zip xs ys) r -> Many ys -> ViaN c n (Zip xs ys) r-viaN' _ c (Many _ m) = ViaN (c, snd <$> M.toAscList m)+forManyN'' :: Proxy xs -> c n (Zip xs ys) r -> Many ys -> CollectorAnyN c n (Zip xs ys) r+forManyN'' _ c (Many _ ys) = CollectorAnyN c (snd <$> M.toAscList ys)  newtype CaseAmendN' (indices :: [Nat]) (larger :: [Type]) (n :: Nat) (zs :: [Type]) r = CaseAmendN' Int  instance ReiterateN (CaseAmendN' indices larger) n (z ': zs) where-    reiterateN (CaseAmendN' lo) = CaseAmendN' lo+    reiterateN = coerce  -- | for each x in @smaller@, convert it to a (k, v) to insert into the x in @larger@-instance (MemberAt (KindAtIndex n indices) x larger) =>-         Case (CaseAmendN' indices larger n) ((x, y) ': zs) (Key, WrappedAny) where-    caseAny (CaseAmendN' lo) v = (Key (lo + i), WrappedAny v)+instance (MemberAt n' x larger, n' ~ KindAtIndex n indices) =>+         CaseAny (CaseAmendN' indices larger n) ((x, y) ': zs) (Int, WrappedAny) where+    caseAny (CaseAmendN' lo) v = (lo + i, WrappedAny v)       where-        i = fromInteger (natVal @(KindAtIndex n indices) Proxy)+        i = fromInteger (natVal @n' Proxy)  ----------------------------------------------------------------------- @@ -813,10 +1041,10 @@ -- @ -- -- @--- 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'+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil'+-- x '^.' ('project' \@'[Int, Maybe Char]) \`shouldBe` (5 :: Int) './' Just \'O' './' 'nil'+-- (x '&' ('project' \@'[Int, Maybe Char]) '.~' ((6 :: Int) './' Just 'P' './' 'nil')) \`shouldBe`+--     (6 :: Int) './' False './' \'X' './' Just \'P' './' 'nil' -- @ project     :: forall smaller larger.@@ -827,12 +1055,49 @@  -- | Polymorphic version of project' project'-    :: forall smaller smaller' larger.-       (Select smaller larger, Amend' smaller smaller' larger)+    :: forall smaller smaller' larger zipped.+       (Select smaller larger, Amend' smaller smaller' larger zipped)     => Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller') project' = lens select (amend' @smaller @smaller' Proxy) {-# INLINE project' #-} +-- | 'selectL' ('view' 'projectL') and 'amendL' ('set' 'projectL') in 'Lens'' form.+--+-- @+-- let x = False './' Tagged \@\"Hi" (5 :: Int) './' Tagged \@Foo False './' Tagged \@Bar \'X' './' Tagged \@\"Bye" \'O' './' 'nil'+-- x '^.' ('projectL' \@'[Foo, Bar] Proxy) \`shouldBe` Tagged \@Foo False './' Tagged \@Bar \'X' './' nil+-- (x '&' ('projectL' \@'[\"Hi", \"Bye"] Proxy) '.~' (Tagged \@\"Hi" (6 :: Int) './' Tagged \@\"Bye" \'P' './' nil)) '`shouldBe`+--     False './' Tagged \@\"Hi" (6 :: Int) './' Tagged \@Foo False './' Tagged \@Bar \'X' './' Tagged \@\"Bye" \'P' './' 'nil'+-- @+projectL+    :: forall ls smaller larger proxy.+       ( Select smaller larger+       , Amend smaller larger+       , smaller ~ KindsAtLabels ls larger+       , IsDistinct ls+       , UniqueLabels ls larger)+    => proxy ls -> Lens' (Many larger) (Many smaller)+projectL p = lens (selectL p) (amendL p)+{-# INLINE projectL #-}++-- | Polymorphic version of projectL'+--+-- @+-- let x = False './' Tagged \@\"Hi" (5 :: Int) './' Tagged \@Foo False './' Tagged \@Bar \'X' './' Tagged \@\"Bye" \'O' './' 'nil'+-- (x '&' ('projectL'' \@'[\"Hi", \"Bye"] Proxy) '.~' (True './' Tagged \@\"Changed" False './' 'nil')) \`shouldBe`+--     False './' True './' Tagged \@Foo False './' Tagged \@Bar \'X' './' Tagged \@\"Changed" False './' 'nil'+-- @+projectL'+    :: forall ls smaller smaller' larger proxy zipped.+       ( Select smaller larger+       , Amend' smaller smaller' larger zipped+       , smaller ~ KindsAtLabels ls larger+       , IsDistinct ls+       , UniqueLabels ls larger)+    => proxy ls -> Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')+projectL' p = lens (selectL p) (amendL' p)+{-# INLINE projectL' #-}+ -- | 'selectN' ('view' 'projectN') and 'amendN' ('set' 'projectN') in 'Lens'' form. -- -- @@@ -840,10 +1105,10 @@ -- @ -- -- @--- 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'+-- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nil'+-- x '^.' ('projectN' \@'[5, 4, 0] Proxy) \`shouldBe` Just \'A' './' (6 :: Int) './' (5 ::Int) './' 'nil'+-- (x '&' ('projectN' \@'[5, 4, 0] Proxy) '.~' (Just \'B' './' (8 :: Int) './' (4 ::Int) './' nil)) \`shouldBe`+--     (4 :: Int) './' False './' \'X' './' Just \'O' './' (8 :: Int) './' Just \'B' './' 'nil' -- @ projectN     :: forall ns smaller larger proxy.@@ -854,136 +1119,94 @@  -- | Polymorphic version of 'projectN' projectN'-    :: forall ns smaller smaller' larger proxy.-       (SelectN ns smaller larger, AmendN' ns smaller smaller' larger)+    :: forall ns smaller smaller' larger proxy zipped.+       (SelectN ns smaller larger, AmendN' ns smaller smaller' larger zipped)     => proxy ns -> Lens (Many larger) (Many (ReplacesIndex ns smaller' larger)) (Many smaller) (Many smaller') projectN' p = lens (selectN p) (amendN' p) {-# INLINE projectN' #-}  ----------------------------------------------------------------------- --- | Stores the left & right Many and a list of Any which must be the same length and types in xs typelist.-newtype EmitEqMany (xs :: [Type]) r = EmitEqMany ([Any], [Any])--instance Reiterate EmitEqMany (x ': xs) where-    -- use of tail here is safe as we are guaranteed the length from the typelist-    reiterate (EmitEqMany (ls, rs)) = EmitEqMany (Partial.tail ls, Partial.tail rs)--instance Eq x => Emit EmitEqMany (x ': xs) Bool where-    emit (EmitEqMany (ls, rs)) = l == r-      where-        -- use of front here is safe as we are guaranteed the length from the typelist-        l = unsafeCoerce (Partial.head ls) :: x-        r = unsafeCoerce (Partial.head rs) :: x+instance Eq (Many_ '[]) where+    _ == _ = True -eqMany-    :: forall xs.-       AFoldable (Collector EmitEqMany xs) Bool-    => Many xs -> Many xs -> [Bool]-eqMany (Many _ lm) (Many _ rm) = afoldr (:) []-    (Collector (EmitEqMany @xs (snd <$> M.toAscList lm, snd <$> M.toAscList rm)))+instance (Eq x, Eq (Many_ xs)) => Eq (Many_ (x ': xs)) where+    ls == rs = case front' ls == front' rs of+        False -> False+        _ -> (aft' ls) == (aft' rs)+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE (==) #-}  -- | Two 'Many's are equal if all their fields equal-instance AFoldable (Collector EmitEqMany xs) Bool => Eq (Many xs) where-    lt == rt = foldr (\e z -> bool False z e) True eqs-      where-        eqs = eqMany lt rt+instance Eq (Many_ xs) => Eq (Many xs) where+    lt == rt = toMany_ lt == toMany_ rt  ----------------------------------------------------------------------- --- | Stores the left & right Many and a list of Any which must be the same length and types in xs typelist.-newtype EmitOrdMany (xs :: [Type]) r = EmitOrdMany ([Any], [Any])--instance Reiterate EmitOrdMany (x ': xs) where-    -- use of tail here is safe as we are guaranteed the length from the typelist-    reiterate (EmitOrdMany (ls, rs)) = EmitOrdMany (Partial.tail ls, Partial.tail rs)--instance Ord x => Emit EmitOrdMany (x ': xs) Ordering where-    emit (EmitOrdMany (ls, rs)) = compare l r-      where-        -- use of front here is safe as we are guaranteed the length from the typelist-        l = unsafeCoerce (Partial.head ls) :: x-        r = unsafeCoerce (Partial.head rs) :: x+instance Ord (Many_ '[]) where+    compare _ _ = EQ -ordMany-    :: forall xs.-       AFoldable (Collector EmitOrdMany xs) Ordering-    => Many xs -> Many xs -> [Ordering]-ordMany (Many _ lm) (Many _ rm) = afoldr (:) []-    (Collector (EmitOrdMany @xs (snd <$> M.toAscList lm, snd <$> M.toAscList rm)))+instance (Ord x, Ord (Many_ xs)) => Ord (Many_ (x ': xs)) where+    compare ls rs = case compare (front' ls) (front' rs) of+        LT -> LT+        GT -> GT+        EQ -> compare (aft' ls) (aft' rs)+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE compare #-}  -- | Two 'Many's are ordered by 'compare'ing their fields in index order-instance (Eq (Many xs), AFoldable (Collector EmitOrdMany xs) Ordering) => Ord (Many xs) where-    compare lt rt = foldr (\o z -> case o of-                                       EQ -> z-                                       o' -> o') EQ ords-      where-        ords = ordMany lt rt+instance Ord (Many_ xs) => Ord (Many xs) where+    compare xs ys = compare (toMany_ xs) (toMany_ ys)  ----------------------------------------------------------------------- --- | Internally uses [Any] like Via, except also handle the empty type list.-newtype EmitShowMany (xs :: [Type]) r = EmitShowMany [Any]--instance Reiterate EmitShowMany (x ': xs) where-    -- use of tail here is safe as we are guaranteed the length from the typelist-    reiterate (EmitShowMany xxs) = EmitShowMany (Partial.tail xxs)--instance Emit EmitShowMany '[] ShowS where-    emit _ = showString "nul"-+instance Show (Many_ '[]) where+    showsPrec d _ = showParen (d > app_prec) $ showString "nil"+      where+        app_prec = 10 -instance Show x => Emit EmitShowMany (x ': xs) ShowS where-    emit (EmitShowMany xxs) = showsPrec (cons_prec + 1) v . showString " ./ "+instance (Show x, Show (Many_ xs)) => Show (Many_ (x ': xs)) where+    showsPrec d ls@(Many_ xs) =+        showParen (d > cons_prec) $+        showsPrec (cons_prec + 1) v .+        showString " ./ " .+        showsPrec cons_prec (aft' ls) -- not (cons-prec+1) for right associativity       where+        cons_prec = 5 -- infixr 5 prefix         -- use of front here is safe as we are guaranteed the length from the typelist-        v = unsafeCoerce (Partial.head xxs) :: x-        cons_prec = 5 -- infixr 5 cons--showMany-    :: forall xs.-       AFoldable (Collector0 EmitShowMany xs) ShowS-    => Many xs -> ShowS-showMany (Many _ m) = afoldr (.) id (Collector0 (EmitShowMany @xs (snd <$> M.toAscList m)))+        v = unsafeCoerce (Partial.head xs) :: x+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE showsPrec #-} --- | @read "5 ./ False ./ 'X' ./ Just 'O' ./ nul" == (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nul'@-instance AFoldable (Collector0 EmitShowMany xs) ShowS => Show (Many xs) where-    showsPrec d t = showParen (d > cons_prec) $ showMany t-      where-        cons_prec = 5 -- infixr 5 cons+-- | Two 'Many's are equal if all their fields equal+instance Show (Many_ xs) => Show (Many xs) where+    showsPrec d xs = showsPrec d (toMany_ xs)  ----------------------------------------------------------------------- -newtype EmitReadMany (xs :: [Type]) r = EmitReadMany Key--instance Reiterate EmitReadMany (x ': xs) where-    reiterate (EmitReadMany (Key i)) = EmitReadMany (Key (i + 1))--instance Emit EmitReadMany '[] (ReadPrec [(Key, WrappedAny)]) where-    emit (EmitReadMany _) = do-        lift $ L.expect (Ident "nul")-        pure []+instance Read (Many_ '[]) where+    readPrec = parens $ prec app_prec $ do+        lift $ L.expect (Ident "nil")+        pure $ Many_ []+      where+        app_prec = 10 -instance Read x => Emit EmitReadMany (x ': xs) (ReadPrec [(Key, WrappedAny)]) where-    emit (EmitReadMany i) = do-        a <- readPrec @x+instance (Read x, Read (Many_ xs)) => Read (Many_ (x ': xs)) where+    readPrec = parens $ prec cons_prec $ do+        a <- step (readPrec @x)         lift $ L.expect (Symbol "./")-        pure [(i, WrappedAny (unsafeCoerce a))]--readMany-    :: forall xs.-       AFoldable (Collector0 EmitReadMany xs) (ReadPrec [(Key, WrappedAny)])-    => Proxy (xs :: [Type]) -> ReadPrec [(Key, WrappedAny)]-readMany _ = afoldr (liftA2 (++)) (pure []) (Collector0 (EmitReadMany @xs (Key 0)))+        as <- readPrec @(Many_ xs) -- no 'step' to allow right associatitive './'+        pure $ prefix' a as+      where+        cons_prec = 5 -- infixr `prefix`+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE readPrec #-} --- | @read "5 ./ False ./ 'X' ./ Just 'O' ./ nul" == (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nul'@-instance (AFoldable (Collector0 EmitReadMany xs) (ReadPrec [(Key, WrappedAny)])) =>-         Read (Many xs) where-    readPrec =-        parens $-        prec 10 $ do-            xs <- readMany @xs Proxy-            pure (Many 0 (fromList' xs))+-- | @read "5 ./ False ./ 'X' ./ Just 'O' ./ nil" == (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nil'@+instance Read (Many_ xs) => Read (Many xs) where+    readPrec = do+        xs <- readPrec @(Many_ xs)+        pure $ fromMany_ xs  -- | 'WrappedAny' avoids the following: -- Illegal type synonym family application in instance: Any
src/Data/Diverse/Type.hs view
@@ -16,8 +16,14 @@ -- | Ensures that @x@ is a unique member of @xs@, and that 'natVal' can be used. type UniqueMember x xs = (Unique x xs, KnownNat (IndexOf x xs)) +-- | Ensures that @x@ is a unique member of @xs@, and that 'natVal' can be used.+type UniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ IndexOf x xs)++-- | Ensures that @x@ is a unique member of @xs@, and that 'natVal' can be used.+type UniqueLabelMember l xs = (UniqueLabel l xs, KnownNat (IndexOf (KindAtLabel l xs) xs))+ -- | Ensures that @x@ is a unique member of @xs@ if it exists, and that 'natVal' can be used.-type MaybeUniqueMember x xs = (Unique x xs, KnownNat (PositionOf x xs))+type MaybeUniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ PositionOf x xs)  -- | Ensures that @x@ is a member of @xs@ at @n@, and that 'natVal' can be used. type MemberAt n x xs = (KnownNat n, x ~ KindAtIndex n xs)@@ -42,6 +48,14 @@ -- | Ensures that @x@ only ever appears once in @xs@ type Unique (x :: k) (xs :: [k]) = UniqueImpl xs x xs +-- | Ensures that the @label@ in @tagged label v@ only ever appears once in @xs@.+type UniqueLabel (l :: k1) (xs :: [k]) = UniqueLabelImpl xs l xs++-- | Ensures that the @label@ list all 'UniqueLabel's+type family UniqueLabels (ls :: [k1]) (xs :: [k]) :: Constraint where+    UniqueLabels '[] xs = ()+    UniqueLabels (l ': ls) xs = (UniqueLabel l xs, UniqueLabels ls xs)+ -- | Get the first index of a type (Indexed by 0) -- Will result in type error if x doesn't exist in xs. type IndexOf (x :: k) (xs :: [k]) = IndexOfImpl xs x xs@@ -54,7 +68,7 @@ type KindAtIndex (n :: Nat) (xs :: [k]) = KindAtIndexImpl n xs n xs  -- | Get the type at a label-type KindAtLabel (l :: k1) (xs :: [k2]) = KindAtLabelImpl l xs xs+type KindAtLabel (l :: k1) (xs :: [k]) = KindAtLabelImpl l xs xs  -- | It's actually ok for the position to be zero, but if it's not zero then the types must match type family KindAtPositionIs (n :: Nat) (x :: k) (xs :: [k]) :: Constraint where@@ -65,6 +79,10 @@ type family KindsAtIndices (ns :: [Nat]) (xs :: [k]) :: [k] where     KindsAtIndices '[] xs = '[]     KindsAtIndices (n ': ns) xs = KindAtIndex n xs ': KindsAtIndices ns xs++type family KindsAtLabels (ls :: [k1]) (xs :: [k]) :: [k] where+    KindsAtLabels '[] xs = '[]+    KindsAtLabels (l ': ls) xs = KindAtLabel l xs ': KindsAtLabels ls xs  -- | The typelist @xs@ without first @x@. It is okay for @x@ not to exist in @xs@ type family Without (x :: k) (xs :: [k]) :: [k] where
src/Data/Diverse/Type/Internal.hs view
@@ -41,7 +41,7 @@ -- | Errors if a type exists in a typelist type family MissingImpl (ctx :: [k]) (y :: k) (xs :: [k]) :: Constraint where     MissingImpl ctx y '[] = ()-    MissingImpl ctx x (x ': xs) = TypeError ('Text "Missing error: ‘"+    MissingImpl ctx x (x ': xs) = TypeError ('Text "Not unique error: ‘"                                              ':<>: 'ShowType x                                              ':<>: 'Text "’"                                              ':<>: 'Text " is a duplicate in "@@ -50,7 +50,20 @@                                              ':<>: 'Text "’")     MissingImpl ctx y (x ': xs) = (MissingImpl ctx y xs) --- | Ensures that the type list contain unique types+-- | Errors if a label exists in a typelist+type family MissingLabelImpl (ctx :: [k]) (l :: k2) (xs :: [k]) :: Constraint where+    MissingLabelImpl ctx y '[] = ()+    MissingLabelImpl ctx l (tagged l x ': xs) = TypeError ('Text "Not unique label error: ‘"+                                             ':<>: 'ShowType l+                                             ':<>: 'Text "’"+                                             ':<>: 'Text " is a duplicate in "+                                             ':<>: 'Text "‘"+                                             ':<>: 'ShowType ctx+                                             ':<>: 'Text "’")+    MissingLabelImpl ctx l (x ': xs) = (MissingLabelImpl ctx l xs)++-- | Ensures that the type list contain unique types.+-- Not implemented as @(xs ~ Nub xs)@ for better type error messages. type family IsDistinctImpl (ctx :: [k]) (xs :: [k]) :: Constraint where     IsDistinctImpl ctx '[] = ()     IsDistinctImpl ctx (x ': xs) = (MissingImpl ctx x xs, IsDistinctImpl ctx xs)@@ -61,6 +74,12 @@     UniqueImpl ctx x (x ': xs) = MissingImpl ctx x xs     UniqueImpl ctx x (y ': xs) = UniqueImpl ctx x xs +-- | Ensures that the @label@ in @tagged label v@ only ever appears once in @xs@.+type family UniqueLabelImpl (ctx :: [k]) (l :: k1) (xs :: [k]) :: Constraint where+    UniqueLabelImpl ctx l '[] = ()+    UniqueLabelImpl ctx l (tagged l x ': xs) = MissingLabelImpl ctx l xs+    UniqueLabelImpl ctx l (y ': xs) = UniqueLabelImpl ctx l xs+ -- | Indexed access into the list type family KindAtIndexImpl (orig :: Nat) (ctx :: [k]) (n :: Nat) (xs :: [k]) :: k where     KindAtIndexImpl i ctx 0 '[] = TypeError ('Text "KindAtIndex error: Index ‘"@@ -74,7 +93,7 @@     KindAtIndexImpl i ctx n (x ': xs) = KindAtIndexImpl i ctx (n - 1) xs  -- | Labelled access into the list-type family KindAtLabelImpl (l :: k1) (ctx :: [k2]) (xs :: [k2]) :: k2 where+type family KindAtLabelImpl (l :: k1) (ctx :: [k]) (xs :: [k]) :: k where     KindAtLabelImpl l ctx '[] = TypeError ('Text "KindAtLabel error: Label ‘"                                        ':<>: 'ShowType l                                        ':<>: 'Text "’"
src/Data/Diverse/Which.hs view
@@ -9,14 +9,17 @@     , pick     , pick0     , pickOnly+    , pickL     , pickN       -- ** Destruction     , obvious     , trial     , trial0+    , trialL     , trialN       -- ** Lens     , facet+    , facetL     , facetN        -- * Multiple types@@ -24,15 +27,18 @@     , Diversify     , diversify     , diversify0+    , diversifyL     , DiversifyN     , diversifyN       -- ** Inverse Injection     , Reinterpret     , reinterpret+    , reinterpretL     , ReinterpretN     , reinterpretN       -- ** Lens     , inject+    , injectL     , injectN        -- * Catamorphism
src/Data/Diverse/Which/Internal.hs view
@@ -23,14 +23,17 @@     , pick     , pick0     , pickOnly+    , pickL     , pickN       -- ** Destruction     , obvious     , trial     , trial0+    , trialL     , trialN       -- ** Lens     , facet+    , facetL     , facetN        -- * Multiple types@@ -38,15 +41,18 @@     , Diversify     , diversify     , diversify0+    , diversifyL     , DiversifyN     , diversifyN       -- ** Inverse Injection     , Reinterpret     , reinterpret+    , reinterpretL     , ReinterpretN     , reinterpretN       -- ** Lens     , inject+    , injectL     , injectN        -- * Catamorphism@@ -60,17 +66,15 @@  import Control.Applicative import Control.Lens-import Data.Diverse.AFoldable+import Control.Monad import Data.Diverse.Case-import Data.Diverse.Collector-import Data.Diverse.Emit import Data.Diverse.Reduce import Data.Diverse.Reiterate import Data.Diverse.Type import Data.Kind import Data.Proxy import qualified GHC.Generics as G-import GHC.Prim (Any)+import GHC.Prim (Any, coerce) import GHC.TypeLits import Text.ParserCombinators.ReadPrec import Text.Read@@ -105,6 +109,10 @@ data Which (xs :: [Type]) = Which {-# UNPACK #-} !Int Any  -- Just like Haskus and HList versions, inferred type is phantom which is wrong+-- representational means:+-- @+-- Coercible '[Int] '[IntLike] => Coercible (Which '[Int]) (Which '[IntLike])+-- @ type role Which representational  ----------------------------------------------@@ -151,8 +159,21 @@ -- 'pick' \'A' \@'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String] -- @ pick :: forall xs x. UniqueMember x xs => x -> Which xs-pick = Which (fromInteger (natVal @(IndexOf x xs) Proxy)) . unsafeCoerce+pick = pick_ +pick_ :: forall x xs n. (KnownNat n, n ~ IndexOf x xs) => x -> Which xs+pick_ = Which (fromInteger (natVal @n Proxy)) . unsafeCoerce++-- | A variation of 'pick' where @x@ is specified via a label+--+-- @+-- let y = 'pickL' \@Foo Proxy (Tagged (5 :: Int)) :: Which '[Bool, Tagged Foo Int, Tagged Bar Char]+--     x = 'trialL' \@Foo Proxy y+-- x `shouldBe` (Right (Tagged 5))+-- @+pickL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> x -> Which xs+pickL _ = pick_ @x+ -- | A variation of 'pick' into a 'Which' of a single type. -- -- @@@ -197,13 +218,32 @@     :: forall x xs.        (UniqueMember x xs)     => Which xs -> Either (Which (Without x xs)) x-trial (Which n v) = let i = fromInteger (natVal @(IndexOf x xs) Proxy)+trial = trial_++trial_+    :: forall x xs n.+       (KnownNat n, n ~ IndexOf x xs)+    => Which xs -> Either (Which (Without x xs)) x+trial_ (Which n v) = let i = fromInteger (natVal @n Proxy)                   in if n == i                      then Right (unsafeCoerce v)                      else if n > i                           then Left (Which (n - 1) v)                           else Left (Which n v) +-- | A variation of 'trial' where x is specified via a label+--+-- @+-- let y = 'pickL' \@Foo Proxy (Tagged (5 :: Int)) :: Which '[Bool, Tagged Foo Int, Tagged Bar Char]+--     x = 'trialL' \@Foo Proxy y+-- x `shouldBe` (Right (Tagged 5))+-- @+trialL+    :: forall l xs x proxy.+       (UniqueLabelMember l xs, x ~ KindAtLabel l xs)+    => proxy l -> Which xs -> Either (Which (Without x xs)) x+trialL _ = trial_ @x+ -- | A variation of a 'Which' 'trial' which 'trial's the first type in the type list. -- -- @@@ -215,7 +255,6 @@            then Right (unsafeCoerce v)            else Left (Which (n - 1) v) - -- | 'trialN' the n-th type of a 'Which', and get 'Either' the 'Right' value or the 'Left'-over possibilities. -- -- @@@ -254,6 +293,17 @@ facet = prism' pick (hush . trial) {-# INLINE facet #-} +-- | 'pickL' ('review' 'facetL') and 'trialL' ('preview' 'facetL') in 'Prism'' form.+--+-- @+-- let y = 'review' ('facetL' \@Bar Proxy) (Tagged (5 :: Int)) :: Which '[Tagged Foo Bool, Tagged Bar Int, Char, Bool, Char]+--     x = 'preview' ('facetL' \@Bar Proxy) y+-- x \`shouldBe` (Just (Tagged 5))+-- @+facetL :: forall l xs x proxy. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Prism' (Which xs) x+facetL p = prism' (pickL p) (hush . trialL p)+{-# INLINE facetL #-}+ -- | 'pickN' ('review' 'facetN') and 'trialN' ('preview' 'facetN') in 'Prism'' form. -- -- @@@ -307,10 +357,30 @@  ------------------------------------------------------------------ +-- | A variation of 'diversify' where @branch@is additionally specified by a labels list.+--+-- @+-- let y = 'pickOnly' (5 :: Tagged Bar Int)+--     y' = 'diversifyL' \@'[Bar] Proxy y :: 'Which' '[Tagged Bar Int, Tagged Foo Bool]+--     y'' = 'diversifyL' \@'[Bar, Foo] Proxy y' :: 'Which' '[Tagged Foo Bool, Tagged Bar Int]+-- 'switch' y'' ('Data.Diverse.CaseTypeable.CaseTypeable' (show . typeRep . (pure \@Proxy))) \`shouldBe` \"Tagged * Bar Int"+-- @+diversifyL+    :: forall ls tree branch proxy.+       ( Diversify tree branch+       , branch ~ KindsAtLabels ls tree+       , UniqueLabels ls tree+       , IsDistinct ls+       )+    => proxy ls -> Which branch -> Which tree+diversifyL _ = which (CaseDiversify @tree @branch @branch)++------------------------------------------------------------------+ -- | A friendlier constraint synonym for 'diversifyN'. type DiversifyN (indices :: [Nat]) (tree :: [Type]) (branch :: [Type]) = (Reduce Which (SwitchN (CaseDiversifyN indices) 0) (KindsAtIndices indices tree) (Which tree), KindsAtIndices indices tree ~ branch) --- | A variation of 'diversify' which uses a Nat list @n@ to specify how to reorder the fields, where+-- | A variation of 'diversify' which uses a Nat list @indices@ to specify how to reorder the fields, where -- -- @ -- indices[branch_idx] = tree_idx@@ -364,21 +434,43 @@ instance Reiterate (CaseReinterpret branch tree) tree' where     reiterate CaseReinterpret = CaseReinterpret -instance ( MaybeUniqueMember x branch+instance ( MaybeUniqueMemberAt n x branch          , comp ~ Complement tree branch-         , MaybeUniqueMember x comp+         , MaybeUniqueMemberAt n' x comp          , Unique x tree -- Compile error to ensure reinterpret only works with unique fields          ) =>          Case (CaseReinterpret branch tree) (x ': tree') (Either (Which comp) (Which branch)) where     case' CaseReinterpret a =-        case fromInteger (natVal @(PositionOf x branch) Proxy) of-            0 -> let j = fromInteger (natVal @(PositionOf x (Complement tree branch)) Proxy)+        case fromInteger (natVal @n Proxy) of+            0 -> let j = fromInteger (natVal @n' Proxy)                  -- safe use of partial! j will never be zero due to check above                  in Left $ Which (j - 1) (unsafeCoerce a)             i -> Right $ Which (i - 1) (unsafeCoerce a)  ------------------------------------------------------------------ +-- | A variation of 'reinterpret' where the @branch@ is additionally specified with a labels list.+--+-- @+-- let y = 'pick' \@[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool] (5 :: Tagged Bar Int)+--     y' = 'reinterpretL' \@[Foo, Bar] Proxy y+--     x = 'pick' \@[Tagged Foo Bool, Tagged Bar Int] (5 :: Tagged Bar Int)+-- y' \`shouldBe` Right x+-- @+reinterpretL+    :: forall ls branch tree proxy.+       ( Reinterpret branch tree+       , branch ~ KindsAtLabels ls tree+       , UniqueLabels ls tree+       , IsDistinct ls+       )+    => proxy ls+    -> Which tree+    -> Either (Which (Complement tree branch)) (Which branch)+reinterpretL _ = which (CaseReinterpret @branch @tree @tree)++------------------------------------------------------------------+ -- | A friendlier constraint synonym for 'reinterpretN'. type ReinterpretN (indices :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (Reduce Which (SwitchN (CaseReinterpretN indices) 0) tree (Maybe (Which (KindsAtIndices indices tree))), KindsAtIndices indices tree ~ branch) @@ -404,9 +496,9 @@ instance ReiterateN (CaseReinterpretN indices) n tree' where     reiterateN CaseReinterpretN = CaseReinterpretN -instance MaybeMemberAt (PositionOf n indices) x branch => Case (CaseReinterpretN indices n) (x ': tree) (Maybe (Which branch)) where+instance (MaybeMemberAt n' x branch, n' ~ PositionOf n indices) => Case (CaseReinterpretN indices n) (x ': tree) (Maybe (Which branch)) where     case' CaseReinterpretN a =-        case fromInteger (natVal @(PositionOf n indices) Proxy) of+        case fromInteger (natVal @n' Proxy) of             0 -> Nothing             i -> Just $ Which (i - 1) (unsafeCoerce a) @@ -430,6 +522,29 @@ inject = prism' diversify (hush . reinterpret) {-# INLINE inject #-} ++-- | 'diversifyL' ('review' 'injectL') and 'reinterpretL' ('preview' 'injectL') in 'Prism'' form.+--+-- @+-- let t = 'pick' \@[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool] (5 :: Tagged Bar Int)+--     b = 'pick' \@'[Tagged Foo Bool, Tagged Bar Int] (5 :: Tagged Bar Int)+--     t' = 'review' ('injectL' \@[Foo, Bar] \@_ \@[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool] Proxy) b+--     b' = 'preview' ('injectL' \@[Foo, Bar] Proxy) t'+-- t \`shouldBe` t'+-- b' \`shouldBe` Just b+-- @+injectL+    :: forall ls branch tree proxy.+       ( Diversify tree branch+       , Reinterpret branch tree+       , branch ~ KindsAtLabels ls tree+       , UniqueLabels ls tree+       , IsDistinct ls+       )+    => proxy ls -> Prism' (Which tree) (Which branch)+injectL p = prism' (diversifyL p) (hush . reinterpretL p)+{-# INLINE injectL #-}+ -- | 'diversifyN' ('review' 'injectN') and 'reinterpretN' ('preview' 'injectN') in 'Prism'' form. -- -- @@@ -456,15 +571,14 @@  -- | 'trial0' each type in a 'Which', and either handle the 'case'' with value discovered, or __'reiterate'__ -- trying the next type in the type list.--- This code will be efficiently compiled into a single case statement in GHC 8.2.1--- See http://hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-2.html instance (Case c (x ': x' ': xs) r, Reduce Which (Switch c) (x' ': xs) r, Reiterate c (x : x' : xs)) =>          Reduce Which (Switch c) (x ': x' ': xs) r where     reduce (Switch c) v =         case trial0 v of             Right a -> case' c a             Left v' -> reduce (Switch (reiterate c)) v'-    {-# INLINE reduce #-}+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE reduce #-}  -- | Terminating case of the loop, ensuring that a instance of @Case '[]@ -- with an empty typelist is not required.@@ -486,7 +600,7 @@ -- 'Data.Diverse.Which.switch' y ( --     'Data.Diverse.Cases.cases' (show \@Bool --         'Data.Diverse.Many../' show \@Int---         'Data.Diverse.Many../' 'Data.Diverse.Many.nul')) \`shouldBe` "5"+--         'Data.Diverse.Many../' 'Data.Diverse.Many.nil')) \`shouldBe` "5" -- @ -- -- Or 'Data.Diverse.CaseTypeable.CaseTypeable' to apply a polymorphic function that work on all 'Typeables'.@@ -508,15 +622,14 @@  -- | 'trial0' each type in a 'Which', and either handle the 'case'' with value discovered, or __'reiterateN'__ -- trying the next type in the type list.--- This code will be efficiently compiled into a single case statement in GHC 8.2.1--- See http://hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-2.html instance (Case (c n) (x ': x' ': xs) r, Reduce Which (SwitchN c (n + 1)) (x' ': xs) r, ReiterateN c n (x : x' : xs)) =>          Reduce Which (SwitchN c n) (x ': x' ': xs) r where     reduce (SwitchN c) v =         case trial0 v of             Right a -> case' c a             Left v' -> reduce (SwitchN (reiterateN c)) v'-    {-# INLINE reduce #-}+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE reduce #-}  -- | Terminating case of the loop, ensuring that a instance of @Case '[]@ -- with an empty typelist is not required.@@ -541,7 +654,7 @@ --         'Data.Diverse.Many../' show \@Bool --         'Data.Diverse.Many../' show \@Bool --         'Data.Diverse.Many../' show \@Int---         'Data.Diverse.Many../' 'Data.Diverse.Many.nul')) \`shouldBe` "5"+--         'Data.Diverse.Many../' 'Data.Diverse.Many.nil')) \`shouldBe` "5" -- @ -- -- Or you may use your own custom instance of 'Case'.@@ -598,7 +711,7 @@  -- | @show ('pick'' \'A') == "pick \'A'"@ instance (Reduce Which (Switch CaseShowWhich) (x ': xs) ShowS) => Show (Which (x ': xs)) where-    showsPrec d v = showParen (d > app_prec) ((showString "pick ") . (which CaseShowWhich v))+    showsPrec d v = showParen (d > app_prec) (which (CaseShowWhich 0) v)       where app_prec = 10  -- | @read "impossible" == 'impossible'@@@ -606,49 +719,59 @@     showsPrec d _ = showParen (d > app_prec) (showString "impossible")       where app_prec = 10 -data CaseShowWhich (xs :: [Type]) r = CaseShowWhich+newtype CaseShowWhich (xs :: [Type]) r = CaseShowWhich Int  instance Reiterate CaseShowWhich (x ': xs) where-    reiterate CaseShowWhich = CaseShowWhich+    reiterate (CaseShowWhich i) = CaseShowWhich (i + 1)  instance Show x => Case CaseShowWhich (x ': xs) ShowS where-    case' _ = showsPrec (app_prec + 1)+    case' (CaseShowWhich i) v = showString "pickN @" . showString (show i) . showString " Proxy " . showsPrec (app_prec + 1) v       where app_prec = 10  ------------------------------------------------------------------ -newtype EmitReadWhich (xs :: [Type]) r = EmitReadWhich Int+class WhichRead v where+    whichReadPrec :: Int -> Int -> ReadPrec v -instance Reiterate EmitReadWhich (x ': xs) where-    reiterate (EmitReadWhich i) = EmitReadWhich (i + 1)+data Which_ (xs ::[Type]) = Which_ Int Any -instance Read x => Emit EmitReadWhich (x ': xs) (ReadPrec (Int, WrappedAny)) where-    emit (EmitReadWhich i) = (\a -> (i, WrappedAny (unsafeCoerce a))) <$> readPrec @x+diversify0' :: forall x xs. Which_ xs -> Which_ (x ': xs)+diversify0' = coerce -readWhich-    :: forall xs.-       AFoldable (Collector EmitReadWhich xs) (ReadPrec (Int, WrappedAny))-    => Proxy (xs :: [Type]) -> ReadPrec (Int, WrappedAny)-readWhich _ = afoldr (<|>) empty (Collector (EmitReadWhich @xs 0))+readWhich_ :: forall x xs. Read x => Int -> Int -> ReadPrec (Which_ (x ': xs))+readWhich_ i j = guard (i == j) >> parens (prec app_prec $ (Which_ i . unsafeCoerce) <$> readPrec @x)+      where+        app_prec = 10 +instance Read x => WhichRead (Which_ '[x]) where+    whichReadPrec = readWhich_++instance (Read x, WhichRead (Which_ (x' ': xs))) => WhichRead (Which_ (x ': x' ': xs)) where+    whichReadPrec i j = readWhich_ i j+               <|> (diversify0' <$> (whichReadPrec i (j + 1) :: ReadPrec (Which_ (x' ': xs))))+    -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types+    {-# NOINLINE whichReadPrec #-}++ -- | This 'Read' instance tries to read using the each type in the typelist, using the first successful type read.-instance AFoldable (Collector EmitReadWhich (x ': xs)) (ReadPrec (Int, WrappedAny)) =>+instance WhichRead (Which_ (x ': xs)) =>          Read (Which (x ': xs)) where     readPrec =-        parens $-        prec 10 $ do-            lift $ L.expect (Ident "pick")-            (n, WrappedAny v) <- step (readWhich @(x ': xs) Proxy)-            pure (Which n v)+        parens $ prec app_prec $ do+            lift $ L.expect (Ident "pickN")+            lift $ L.expect (Punc "@")+            i <- lift L.readDecP+            lift $ L.expect (Ident "Proxy")+            Which_ n v <- whichReadPrec i 0 :: ReadPrec (Which_ (x ': xs))+            pure $ Which n v+      where+        app_prec = 10  -- | @read "impossible" == 'impossible'@ instance Read (Which '[]) where     readPrec =-        parens $-        prec 10 $ do+        parens $ prec app_prec $ do             lift $ L.expect (Ident "impossible")             pure impossible---- | 'WrappedAny' avoids the following:--- Illegal type synonym family application in instance: Any-newtype WrappedAny = WrappedAny Any+      where+        app_prec = 10
test/Data/Diverse/ManySpec.hs view
@@ -10,8 +10,8 @@  import Control.Lens import Data.Diverse-import Data.Typeable import Data.Tagged+import Data.Typeable import Test.Hspec  -- `main` is here so that this module can be run from GHCi on its own.  It is@@ -26,7 +26,7 @@ spec = do     describe "Many" $ do         it "is a Typeable" $ do-            let x = (5 :: Int) ./ False ./ nul+            let x = (5 :: Int) ./ False ./ nil                 y = cast x :: Maybe (Many '[Int, String])                 z = cast x :: Maybe (Many '[Int, Bool])             y `shouldBe` Nothing@@ -34,22 +34,25 @@             (show . typeRep . (pure @Proxy) $ x) `shouldBe` "Many (': * Int (': * Bool '[]))"          it "is a Read and Show" $ do-            let s = "5 ./ False ./ 'X' ./ Just 'O' ./ nul"+            let s = "5 ./ False ./ 'X' ./ Just 'O' ./ nil"+                s' = "5 ./ False ./ 'X' ./ (Just 'O' ./ (nil))"                 x = read s :: Many '[Int, Bool, Char, Maybe Char]+                x' = read s' :: Many '[Int, Bool, Char, Maybe Char]             show x `shouldBe` s+            show x' `shouldBe` s          it "is a Eq" $ do-            let s = "5 ./ False ./ 'X' ./ Just 'O' ./ nul"+            let s = "5 ./ False ./ 'X' ./ Just 'O' ./ nil"                 x = read s :: Many '[Int, Bool, Char, Maybe Char]-                y = 5 ./ False ./ 'X' ./ Just 'O' ./ nul+                y = 5 ./ False ./ 'X' ./ Just 'O' ./ nil             x `shouldBe` y          it "is an Ord" $ do-            let s = "5 ./ False ./ 'X' ./ Just 'O' ./ nul"+            let s = "5 ./ False ./ 'X' ./ Just 'O' ./ nil"                 x = read s :: Many '[Int, Bool, Char, Maybe Char]-                y5o = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-                y4o = (4 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-                y5p = (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul+                y5o = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+                y4o = (4 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+                y5p = (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nil             compare x y5o `shouldBe` EQ             compare y4o y5o `shouldBe` LT             compare y5o y4o `shouldBe` GT@@ -57,16 +60,16 @@             compare y5p y5o `shouldBe` GT          it "can converted to and from a tuple" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil                 t = ((5 :: Int), False, 'X', Just 'O')             x `shouldBe` toMany' t             x `shouldBe` review _Many' t             t `shouldBe` fromMany' x             t `shouldBe` view _Many' x -        it "can construct using 'single', 'nul', 'prefix', 'postfix', 'append'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-                x' = (5 :: Int) `prefix` False `prefix` 'X' `prefix` Just 'O' `prefix` nul+        it "can construct using 'single', 'nil', 'prefix', 'postfix', 'append'" $ do+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+                x' = (5 :: Int) `prefix` False `prefix` 'X' `prefix` Just 'O' `prefix` nil                 y = single (5 :: Int) \. False \. 'X' \. Just 'O'                 y' = single (5 :: Int) `postfix` False `postfix` 'X' `postfix` Just 'O'                 a = single (5 :: Int) `postfix` False@@ -78,14 +81,14 @@             a `append` b `shouldBe` x          it "can contain multiple fields of the same type" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-                y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            (x /./ (6 :: Int) ./ Just 'A' ./ nul) `shouldBe` y+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+                y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            (x /./ (6 :: Int) ./ Just 'A' ./ nil) `shouldBe` y          it "can destruct using 'front', 'back', 'aft', 'fore'" $ do             let a = (x ./ y) \. z                 x = 5 :: Int-                y = single False ./ 'X' ./ nul+                y = single False ./ 'X' ./ nil                 z = Just 'O'             front a `shouldBe` x             back a `shouldBe` z@@ -93,21 +96,21 @@             fore a `shouldBe` x ./ y          it "has getter for unique fields using 'fetch'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil             fetch @Int x `shouldBe` 5             fetch @Bool x `shouldBe` False             fetch @Char x `shouldBe` 'X'             fetch @(Maybe Char) x `shouldBe` Just 'O'          it "has getter for for unique fields using 'fetchN'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil             fetchN @0 Proxy x `shouldBe` 5             fetchN @1 Proxy x `shouldBe` False             fetchN @2 Proxy x `shouldBe` 'X'             fetchN @3 Proxy x `shouldBe` Just 'O'          it "has getter for duplicate fields using 'fetchN'" $ do-            let y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            let y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             fetchN @0 Proxy y `shouldBe` 5             fetchN @1 Proxy y `shouldBe` False             fetchN @2 Proxy y `shouldBe` 'X'@@ -116,213 +119,264 @@             fetchN @5 Proxy y `shouldBe` Just 'A'          it "with duplicate fields can still use 'fetch' for unique fields" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             fetch @Bool x `shouldBe` False             fetch @Char x `shouldBe` 'X' -        it "can 'fetch' usng tagged labels" $ do-            let y = (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+        it "has getter for unique labels using 'fetchL'" $ do+            let y = (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Tagged @"Hello" (6 :: Int) ./ nil             fetch @(Tagged Foo _) y `shouldBe` Tagged @Foo 'X'+            fetchL @Foo Proxy y `shouldBe` Tagged @Foo 'X'+            fetchL @"Hello" Proxy y `shouldBe` Tagged @"Hello" (6 :: Int)          it "has setter for unique fields using 'replace'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-            replace @Int x 6 `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-            replace x True `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nul-            replace x 'O' `shouldBe` (5 :: Int) ./ False ./ 'O' ./ Just 'O' ./ nul-            replace x (Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+            replace @Int x 6 `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+            replace x True `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nil+            replace x 'O' `shouldBe` (5 :: Int) ./ False ./ 'O' ./ Just 'O' ./ nil+            replace x (Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nil          it "has polymorphic setter for unique fields using 'replace'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-            replace' @Int Proxy x 'Z' `shouldBe` 'Z' ./ False ./ 'X' ./ Just 'O' ./ nul-            replace' @Bool Proxy x 'Z' `shouldBe` (5 :: Int) ./ 'Z' ./ 'X' ./ Just 'O' ./ nul-            replace' @(Maybe Char) Proxy x 'Z' `shouldBe` (5 :: Int) ./ False ./ 'X' ./ 'Z' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+            replace' @Int Proxy x 'Z' `shouldBe` 'Z' ./ False ./ 'X' ./ Just 'O' ./ nil+            replace' @Bool Proxy x 'Z' `shouldBe` (5 :: Int) ./ 'Z' ./ 'X' ./ Just 'O' ./ nil+            replace' @(Maybe Char) Proxy x 'Z' `shouldBe` (5 :: Int) ./ False ./ 'X' ./ 'Z' ./ nil +        it "has setter for unique labels using 'replaceL'" $ do+            let y = (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Tagged @"Hello" (6 :: Int) ./ nil+            replace @(Tagged Foo _) y (Tagged @Foo 'Y') `shouldBe`+                (5 :: Int) ./ False ./ Tagged @Foo 'Y' ./ Tagged @"Hello" (6 :: Int) ./ nil+            replaceL @Foo Proxy y (Tagged @Foo 'Y') `shouldBe`+                (5 :: Int) ./ False ./ Tagged @Foo 'Y' ./ Tagged @"Hello" (6 :: Int) ./ nil+            replaceL @"Hello" Proxy y (Tagged @"Hello" 7) `shouldBe`+                (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Tagged @"Hello" (7 :: Int) ./ nil++        it "has polymorphic setter for unique labels using 'replaceL'" $ do+            let y = (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Tagged @"Hello" (6 :: Int) ./ nil+            replace' @(Tagged Foo Char) Proxy y (Tagged @Bar 'Y') `shouldBe`+                (5 :: Int) ./ False ./ Tagged @Bar 'Y' ./ Tagged @"Hello" (6 :: Int) ./ nil+            replaceL' @Foo Proxy y (Tagged @Bar 'Y') `shouldBe`+                (5 :: Int) ./ False ./ Tagged @Bar 'Y' ./ Tagged @"Hello" (6 :: Int) ./ nil+            replaceL' @"Hello" Proxy y (Tagged @"Hello" False) `shouldBe`+                (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Tagged @"Hello" False ./ nil+         it "has setter for unique fields using 'replaceN'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil             replaceN @0 Proxy x (7 :: Int) `shouldBe`-                (7 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul+                (7 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil             replaceN @1 Proxy x True `shouldBe`-                (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nul+                (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nil             replaceN @2 Proxy x 'Y' `shouldBe`-                (5 :: Int) ./ False ./ 'Y' ./ Just 'O' ./ nul+                (5 :: Int) ./ False ./ 'Y' ./ Just 'O' ./ nil             replaceN @3 Proxy x (Just 'P') `shouldBe`-                (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul+                (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nil          it "has polymorphic setter using 'replaceN''" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil             replaceN' @0 Proxy x True `shouldBe`-                True ./ False ./ 'X' ./ Just 'O' ./ nul-            let y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+                True ./ False ./ 'X' ./ Just 'O' ./ nil+            let y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             replaceN' @1 Proxy y 'Y' `shouldBe`-                (5 :: Int) ./ 'Y' ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+                (5 :: Int) ./ 'Y' ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             replaceN' @5 Proxy y 'Y' `shouldBe`-                (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ 'Y' ./ nul+                (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ 'Y' ./ nil          it "has setter for duplicate fields using 'replaceN'" $ do-            let y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            let y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             replaceN @0 Proxy y (7 :: Int) `shouldBe`-                (7 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+                (7 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             replaceN @1 Proxy y True `shouldBe`-                (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+                (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             replaceN @2 Proxy y 'Y' `shouldBe`-                (5 :: Int) ./ False ./ 'Y' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+                (5 :: Int) ./ False ./ 'Y' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             replaceN @3 Proxy y (Just 'P') `shouldBe`-                (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ (6 :: Int) ./ Just 'A' ./ nul+                (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ (6 :: Int) ./ Just 'A' ./ nil             replaceN @4 Proxy y (8 :: Int) `shouldBe`-                (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just 'A' ./ nul+                (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just 'A' ./ nil             replaceN @5 Proxy y (Just 'B') `shouldBe`-                (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'B' ./ nul+                (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'B' ./ nil          it "has setter for unique fields using 'replace' (even if there are other duplicate fields)" $ do-            let y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            let y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             replace @Bool y True `shouldBe`-                (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+                (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             replace @Char y 'Y' `shouldBe`-                (5 :: Int) ./ False ./ 'Y' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul--        it "can 'replace' usng tagged labels" $ do-            let y = (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            replace @(Tagged Foo _) y (Tagged @Foo 'Y') `shouldBe`-                (5 :: Int) ./ False ./ Tagged @Foo 'Y' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul--        it "can 'replace'' polymorphically usng tagged labels" $ do-            let y = (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            replace' @(Tagged Foo Char) Proxy y (Tagged @Bar 'Y') `shouldBe`-                (5 :: Int) ./ False ./ Tagged @Bar 'Y' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+                (5 :: Int) ./ False ./ 'Y' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil          it "has getter/setter lens using 'item'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil             x ^. item @Int `shouldBe` 5-            (x & item @Int .~ 6) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul+            (x & item @Int .~ 6) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil             x ^. item @Bool `shouldBe` False-            (x & item @Bool .~ True) `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nul+            (x & item @Bool .~ True) `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nil             x ^. item @Char `shouldBe` 'X'             x ^. item @(Maybe Char) `shouldBe` Just 'O'          it "has polymorphic getter/setter lens using 'item''" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-            (x & item' @(Maybe Char) .~ Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul-            (x & item' @Int .~ 'Z') `shouldBe` 'Z' ./ False ./ 'X' ./ Just 'O' ./ nul-            (x & item' @Bool .~ 'Z') `shouldBe` (5 :: Int) ./ 'Z' ./ 'X' ./ Just 'O' ./ nul-            (x & item' @Char .~ True) `shouldBe` (5 :: Int) ./ False ./ True ./ Just 'O' ./ nul-            (x & item' @(Maybe Char) .~ 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ 'P' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+            (x & item' @(Maybe Char) .~ Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nil+            (x & item' @Int .~ 'Z') `shouldBe` 'Z' ./ False ./ 'X' ./ Just 'O' ./ nil+            (x & item' @Bool .~ 'Z') `shouldBe` (5 :: Int) ./ 'Z' ./ 'X' ./ Just 'O' ./ nil+            (x & item' @Char .~ True) `shouldBe` (5 :: Int) ./ False ./ True ./ Just 'O' ./ nil+            (x & item' @(Maybe Char) .~ 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ 'P' ./ nil +        it "has getter/setter lens using 'item'" $ do+            let x = (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ nil+            x ^. itemL @Foo Proxy `shouldBe` Tagged @Foo False+            (x & itemL @Foo Proxy .~ Tagged @Foo True) `shouldBe` (5 :: Int) ./ Tagged @Foo True ./ Tagged @Bar 'X' ./ nil++        it "has polymorphic getter/setter lens using 'itemL''" $ do+            let x = (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ nil+            (x & itemL' @Foo Proxy .~ "foo") `shouldBe` (5 :: Int) ./ "foo" ./ Tagged @Bar 'X' ./ nil+         it "has getter/setter lens for duplicate fields using 'itemN'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             x ^. itemN (Proxy @0) `shouldBe` 5-            (x & itemN (Proxy @0) .~ 6) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            (x & itemN (Proxy @0) .~ 6) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             x ^. itemN (Proxy @1) `shouldBe` False-            (x & itemN (Proxy @1) .~ True) `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            (x & itemN (Proxy @1) .~ True) `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             x ^. itemN (Proxy @2) `shouldBe` 'X'-            (x & itemN (Proxy @2) .~ 'O') `shouldBe` (5 :: Int) ./ False ./ 'O' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            (x & itemN (Proxy @2) .~ 'O') `shouldBe` (5 :: Int) ./ False ./ 'O' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             x ^. itemN (Proxy @3) `shouldBe` Just 'O'-            (x & itemN (Proxy @3) .~ Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ (6 :: Int) ./ Just 'A' ./ nul+            (x & itemN (Proxy @3) .~ Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ (6 :: Int) ./ Just 'A' ./ nil             x ^. itemN (Proxy @4) `shouldBe` 6-            (x & itemN (Proxy @4) .~ 7) `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (7 :: Int) ./ Just 'A' ./ nul+            (x & itemN (Proxy @4) .~ 7) `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (7 :: Int) ./ Just 'A' ./ nil             x ^. itemN (Proxy @5) `shouldBe` Just 'A'-            (x & itemN (Proxy @5) .~ Just 'B') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'B' ./ nul+            (x & itemN (Proxy @5) .~ Just 'B') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'B' ./ nil          it "has polymorphic getter/setter lens for duplicate fields using 'itemN''" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            (x & itemN' (Proxy @0) .~ "Foo") `shouldBe` "Foo" ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            (x & itemN' (Proxy @1) .~ "Foo") `shouldBe` (5 :: Int) ./ "Foo" ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            (x & itemN' (Proxy @2) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ "Foo" ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            (x & itemN' (Proxy @3) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ "Foo" ./ (6 :: Int) ./ Just 'A' ./ nul-            (x & itemN' (Proxy @4) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ "Foo" ./ Just 'A' ./ nul-            (x & itemN' (Proxy @5) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ "Foo" ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            (x & itemN' (Proxy @0) .~ "Foo") `shouldBe` "Foo" ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            (x & itemN' (Proxy @1) .~ "Foo") `shouldBe` (5 :: Int) ./ "Foo" ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            (x & itemN' (Proxy @2) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ "Foo" ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            (x & itemN' (Proxy @3) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ "Foo" ./ (6 :: Int) ./ Just 'A' ./ nil+            (x & itemN' (Proxy @4) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ "Foo" ./ Just 'A' ./ nil+            (x & itemN' (Proxy @5) .~ "Foo") `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ "Foo" ./ nil          it "has getter for multiple fields using 'select'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-            select @'[Int, Maybe Char] x `shouldBe` (5 :: Int) ./ Just 'O' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+            select @'[Int, Maybe Char] x `shouldBe` (5 :: Int) ./ Just 'O' ./ nil +        it "has getter for multiple labelled fields using 'selectL'" $ do+            let x = False ./ Tagged @"Hi" (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Bye" 'O' ./ nil+            selectL @'[Foo, Bar] Proxy x `shouldBe` Tagged @Foo False ./ Tagged @Bar 'X' ./ nil+            selectL @'["Hi", "Bye"] Proxy x `shouldBe` Tagged @"Hi" (5 :: Int) ./ Tagged @"Bye" 'O' ./ nil+            -- below won't compile because the type of labels must match+            -- selectL @'["Hi", 'Foo, "Bye"] Proxy x `shouldBe` Tagged @"Hi" (5 :: Int) ./ Tagged @Foo False ./ Tagged @"Bye" 'O' ./ nil+         it "can reorder fields using 'select' or 'selectN'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-            select @'[Bool, Int, Maybe Char] x `shouldBe` False ./ (5 :: Int) ./ Just 'O' ./ nul-            let y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+            select @'[Bool, Int, Maybe Char] x `shouldBe` False ./ (5 :: Int) ./ Just 'O' ./ nil+            let y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             selectN (Proxy @'[5, 4, 0, 1, 3, 2]) y `shouldBe`-                Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ False ./ Just 'O' ./ 'X' ./ nul+                Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ False ./ Just 'O' ./ 'X' ./ nil          it "has getter for multiple fields with duplicates using 'selectN'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            selectN (Proxy @'[5, 4, 0]) x `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            selectN (Proxy @'[5, 4, 0]) x `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nil          it "can't select into types from indistinct fields" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             -- Compile error: Int is a duplicate-            -- select @[Bool, Char, Int] x `shouldBe` False ./ 'X' ./ (5 :: Int) ./ nul-            x `shouldBe`  x+            -- select @[Bool, Char, Int] x `shouldBe` False ./ 'X' ./ (5 :: Int) ./ nil+            x `shouldBe` x          it "with duplicate fields has getter for multiple unique fields 'select'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            select @'[Bool, Char] x `shouldBe` False ./ 'X' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            select @'[Bool, Char] x `shouldBe` False ./ 'X' ./ nil          it "has setter for multiple fields using 'amend'" $ do-            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+            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          it "has polymorphc setter for multiple fields using 'amend'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-            amend' @'[Int, Maybe Char] Proxy x ("Foo" ./ "Bar" ./ nul) `shouldBe` "Foo" ./ False ./ 'X' ./ "Bar" ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+            amend' @'[Int, Maybe Char] Proxy x ("Foo" ./ "Bar" ./ nil) `shouldBe` "Foo" ./ False ./ 'X' ./ "Bar" ./ nil +        it "has setter for multiple labelled fields using 'amendL'" $ do+            let x = False ./ Tagged @"Hi" (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Bye" 'O' ./ nil+            amendL @'[Foo, Bar] Proxy 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"] Proxy 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++        it "has polymorphic setter for multiple labelled fields using 'amendL'" $ do+            let x = False ./ Tagged @"Hi" (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Bye" 'O' ./ nil+            amendL' @'[Foo, Bar] Proxy x ('Y' ./ True ./ nil) `shouldBe`+                False ./ Tagged @"Hi" (5 :: Int) ./ 'Y' ./ True ./ Tagged @"Bye" 'O' ./ nil+            amendL' @'["Hi", "Bye"] Proxy x (True ./ Tagged @"Changed" True ./ nil) `shouldBe`+                False ./ True ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Changed" True ./ nil+         it "has setter for multiple fields with duplicates using 'amendN'" $ do-            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+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            amendN (Proxy @'[5, 4, 0]) x (Just 'B' ./ (8 :: Int) ./ (4 ::Int) ./ nil) `shouldBe`+                (4 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just 'B' ./ nil          it "has polymorphic setter for multiple fields with duplicates using 'amendN''" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            amendN' @'[5, 4, 0] Proxy x ("Foo" ./ Just 'B' ./ 'Z' ./ nul) `shouldBe`-                'Z' ./ False ./ 'X' ./ Just 'O' ./ Just 'B' ./ "Foo" ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            amendN' @'[5, 4, 0] Proxy x ("Foo" ./ Just 'B' ./ 'Z' ./ nil) `shouldBe`+                'Z' ./ False ./ 'X' ./ Just 'O' ./ Just 'B' ./ "Foo" ./ nil          it "can't amend into types from indistinct fields" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             -- Compile error: Int is a duplicate-            -- amend @ '[Bool, Char, Int] x (True ./ 'B' ./ (8 :: Int) ./ nul) `shouldBe`-            --     (5 :: Int) ./ True ./ 'B' ./ Just 'O' ./ (8 :: Int) ./ Just 'A' ./ nul+            -- amend @ '[Bool, Char, Int] x (True ./ 'B' ./ (8 :: Int) ./ nil) `shouldBe`+            --     (5 :: Int) ./ True ./ 'B' ./ Just 'O' ./ (8 :: Int) ./ Just 'A' ./ nil             x `shouldBe` x          it "with duplicate fields has setter for unique fields 'amend'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            amend @ '[Bool, Char] x (True ./ 'B' ./ nul) `shouldBe`-                (5 :: Int) ./ True ./ 'B' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            amend @ '[Bool, Char] x (True ./ 'B' ./ nil) `shouldBe`+                (5 :: Int) ./ True ./ 'B' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil          it "has getter/setter lens for multiple fields using 'project'" $ do-            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+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+            x ^. (project @'[Int, Maybe Char]) `shouldBe` (5 :: Int) ./ Just 'O' ./ nil+            (x & (project @'[Int, Maybe Char]) .~ ((6 :: Int) ./ Just 'P' ./ nil)) `shouldBe`+                (6 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nil          it "has polymorphic getter/setter lens for multiple fields using 'project'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-            (x & (project' @'[Int, Maybe Char]) .~ ("Foo" ./ Just "Bar" ./ nul)) `shouldBe`-                "Foo" ./ False ./ 'X' ./ Just "Bar" ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil+            (x & (project' @'[Int, Maybe Char]) .~ ("Foo" ./ Just "Bar" ./ nil)) `shouldBe`+                "Foo" ./ False ./ 'X' ./ Just "Bar" ./ nil +        it "has getter/setter lens for multiple labelled fields using 'projectL'" $ do+            let x = False ./ Tagged @"Hi" (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Bye" 'O' ./ nil+            x ^. (projectL @'[Foo, Bar] Proxy) `shouldBe` Tagged @Foo False ./ Tagged @Bar 'X' ./ nil+            (x & (projectL @'["Hi", "Bye"] Proxy) .~ (Tagged @"Hi" (6 :: Int) ./ Tagged @"Bye" 'P' ./ nil)) `shouldBe`+                False ./ Tagged @"Hi" (6 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Bye" 'P' ./ nil++        it "has polymorphic getter/setter lens for multiple labelled fields using 'projectL''" $ do+            let x = False ./ Tagged @"Hi" (5 :: Int) ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Bye" 'O' ./ nil+            (x & (projectL' @'["Hi", "Bye"] Proxy) .~ (True ./ Tagged @"Changed" False ./ nil)) `shouldBe`+                False ./ True ./ Tagged @Foo False ./ Tagged @Bar 'X' ./ Tagged @"Changed" False ./ nil+         it "has getter/setter lens for multiple fields with duplicates using 'projectN'" $ do-            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+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            x ^. (projectN @'[5, 4, 0] Proxy) `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nil+            (x & (projectN @'[5, 4, 0] Proxy) .~ (Just 'B' ./ (8 :: Int) ./ (4 ::Int) ./ nil)) `shouldBe`+                (4 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just 'B' ./ nil          it "has polymorphic getter/setter lens for multiple fields with duplicates using 'projectN'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            (x & (projectN' @'[5, 4, 0] Proxy) .~ (Just "Foo" ./ (8 :: Int) ./ "Bar" ./ nul)) `shouldBe`-                "Bar" ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just "Foo" ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+            (x & (projectN' @'[5, 4, 0] Proxy) .~ (Just "Foo" ./ (8 :: Int) ./ "Bar" ./ nil)) `shouldBe`+                "Bar" ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just "Foo" ./ nil          it "can be folded with 'Many' handlers using 'forMany' or 'collect'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-                y = show @Int ./ show @Char ./ show @(Maybe Char) ./ show @Bool ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil+                y = show @Int ./ show @Char ./ show @(Maybe Char) ./ show @Bool ./ nil                 ret = ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"]             afoldr (:) [] (collect x (cases y)) `shouldBe` ret             afoldr (:) [] (forMany (cases y) x) `shouldBe` ret             afoldr (:) [] (forMany (cases y) x) `shouldBe` ret          it "can be folded with single 'CaseTypeable' handlers using 'forMany' or 'collect'" $ do-            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil             afoldr (:) [] (forMany (CaseTypeable (show . typeRep . (pure @Proxy))) x) `shouldBe` ["Int", "Bool", "Char", "Maybe Char", "Int", "Maybe Char"]          it "can be folded with 'Many' handlers in index order using 'forManyN' or 'collectN'" $ do-            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+            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                 ret = ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"]             afoldr (:) [] (collectN x (casesN y)) `shouldBe` ret             afoldr (:) [] (forManyN (casesN y) x) `shouldBe` ret
test/Data/Diverse/WhichSpec.hs view
@@ -10,9 +10,15 @@  import Control.Lens import Data.Diverse+import Data.Tagged import Data.Typeable import Test.Hspec +data Foo+data Bar+data Hi+data Bye+ -- `main` is here so that this module can be run from GHCi on its own.  It is -- not needed for automatic spec discovery. main :: IO ()@@ -26,10 +32,14 @@ spec = do     describe "Which" $ do +        it "is a Show" $ do+            let x = pickN @0 Proxy 5 :: Which '[Int, Bool]+            show x `shouldBe` "pickN @0 Proxy 5"+         it "is a Read and Show" $ do-            let s = "pick 5"+            let s = "pickN @0 Proxy 5"                 x = read s :: Which '[Int, Bool]-            show x `shouldBe` "pick 5"+            show x `shouldBe` s             "impossible" `shouldBe` show impossible             "impossible" `shouldBe` show (read "impossible" :: Which '[]) @@ -52,6 +62,11 @@                 x = hush $ trial @Int y             x `shouldBe` (Just 5) +        it "can be constructed by label with 'pickL' and destructed with 'trialL'" $ do+            let y = pickL @Foo Proxy (Tagged (5 :: Int)) :: Which '[Bool, Tagged Foo Int, Tagged Bar Char]+                x = hush $ trialL @Foo Proxy y+            x `shouldBe` (Just (Tagged 5))+         it "may contain possiblities of duplicate types" $ do             let y = pick (5 :: Int) :: Which '[Bool, Int, Char, Bool, Char]                 x = hush $ trial @Int y@@ -121,6 +136,11 @@                 x = preview (facet @Int) y             x `shouldBe` (Just 5) +        it "can be constructed and destructed by label with 'facetL'" $ do+            let y = review (facetL @Bar Proxy) (Tagged (5 :: Int)) :: Which '[Tagged Foo Bool, Tagged Bar Int, Char, Bool, Char]+                x = preview (facetL @Bar Proxy) y+            x `shouldBe` (Just (Tagged 5))+         it "can be constructed and destructed by index with 'facetN'" $ do             let y = review (facetN (Proxy @4)) (5 :: Int) :: Which '[Bool, Int, Char, Bool, Int, Char]                 x = preview (facetN (Proxy @4)) y@@ -132,6 +152,12 @@                 y'' = diversify @[Bool, Int] y'             switch y'' (CaseTypeable (show . typeRep . (pure @Proxy))) `shouldBe` "Int" +        it "can be extended and rearranged by type with 'diversify'" $ do+            let y = pickOnly (5 :: Tagged Bar Int)+                y' = diversifyL @'[Bar] Proxy y :: Which '[Tagged Bar Int, Tagged Foo Bool]+                y'' = diversifyL @'[Bar, Foo] Proxy y' :: Which '[Tagged Foo Bool, Tagged Bar Int]+            switch y'' (CaseTypeable (show . typeRep . (pure @Proxy))) `shouldBe` "Tagged * Bar Int"+         it "can be extended and rearranged by index with 'diversifyN'" $ do             let y = pickOnly (5 :: Int)                 y' = diversifyN @'[0] @[Int, Bool] Proxy y@@ -160,6 +186,12 @@             let c = reinterpret @[String, Int] y             c `shouldBe` Right (pick (5 :: Int)) +        it "can be 'reinterpretL'ed by label into a totally different Which" $ do+            let y = pick @[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool] (5 :: Tagged Bar Int)+                y' = reinterpretL @[Foo, Bar] Proxy y+                x = pick @[Tagged Foo Bool, Tagged Bar Int] (5 :: Tagged Bar Int)+            y' `shouldBe` Right x+         it "the 'reinterpret' type can contain indistinct fields if they aren't in the original 'Many'" $ do             let y = pick @[Int, Char] (5 :: Int)                 x = reinterpret @[String, String, Char, Bool] y@@ -193,6 +225,14 @@             let y' = preview (inject @[String, Int]) y             y' `shouldBe` Just (pick (5 :: Int)) +        it "can be 'diversifyL'ed and 'reinterpretedL' by label with 'injectL'" $ do+            let t = pick @[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool] (5 :: Tagged Bar Int)+                b = pick @'[Tagged Foo Bool, Tagged Bar Int] (5 :: Tagged Bar Int)+                t' = review (injectL @[Foo, Bar] @_ @[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool] Proxy) b+                b' = preview (injectL @[Foo, Bar] Proxy) t'+            t `shouldBe` t'+            b' `shouldBe` Just b+         it "can be 'diversifyN'ed and 'reinterpretedN' by index with 'injectN'" $ do             let x = pick (5 :: Int) :: Which '[String, Int]                 y = review (injectN @[3, 1] @_ @[Bool, Int, Char, String] Proxy) x@@ -205,7 +245,7 @@             switch y (                 cases (show @Bool                     ./ show @Int-                    ./ nul)) `shouldBe` "5"+                    ./ nil)) `shouldBe` "5"          it "can be 'switch'ed with 'Many' handlers with extraneous content" $ do             let y = pick (5 :: Int) :: Which '[Int, Bool]@@ -216,7 +256,7 @@                     ./ show @Char                     ./ 'X'                     ./ False-                    ./ nul+                    ./ nil                 )) `shouldBe` "5"          it "can be 'switchN'ed with 'Many' handlers in index order" $ do@@ -226,7 +266,7 @@                     ./ show @Bool                     ./ show @Bool                     ./ show @Int-                    ./ nul)) `shouldBe` "5"+                    ./ nil)) `shouldBe` "5"          it "can be switched with a single 'CaseTypeable' handler" $ do             let y = pick (5 :: Int) :: Which '[Int, Bool]