packages feed

data-diverse 0.2.1.0 → 0.3.0.0

raw patch · 10 files changed

+402/−210 lines, 10 filesdep ~data-diversePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: data-diverse

API changes (from Hackage documentation)

- Data.Diverse.Many: (.^.) :: forall x xs proxy. UniqueMember x xs => Many xs -> proxy x -> x
- Data.Diverse.Many: (.~.) :: forall x xs. UniqueMember x xs => Many xs -> x -> Many xs
- Data.Diverse.Many: (\^.) :: forall smaller larger proxy. Narrow smaller larger => Many larger -> proxy smaller -> Many smaller
- Data.Diverse.Many: (\~.) :: forall smaller larger. Amend smaller larger => Many larger -> Many smaller -> Many larger
- Data.Diverse.Many: infixl 1 \~.
- Data.Diverse.Many: infixl 8 \^.
- Data.Diverse.Many: narrow :: forall smaller larger. Narrow smaller larger => Many larger -> Many smaller
- Data.Diverse.Many: narrowN :: forall ns smaller larger proxy. NarrowN ns smaller larger => proxy ns -> Many larger -> Many smaller
- Data.Diverse.Many: type Narrow (smaller :: [Type]) (larger :: [Type]) = AFoldable (Collector (Via (CaseNarrow smaller larger)) larger) [(Key, WrappedAny)]
- Data.Diverse.Many: type NarrowN (ns :: [Nat]) (smaller :: [Type]) (larger :: [Type]) = (AFoldable (CollectorN (ViaN (CaseNarrowN ns smaller)) 0 larger) [(Key, WrappedAny)], smaller ~ KindsAtIndices ns larger, IsDistinct ns)
- Data.Diverse.Many.Internal: (.^.) :: forall x xs proxy. UniqueMember x xs => Many xs -> proxy x -> x
- Data.Diverse.Many.Internal: (.~.) :: forall x xs. UniqueMember x xs => Many xs -> x -> Many xs
- Data.Diverse.Many.Internal: (\^.) :: forall smaller larger proxy. Narrow smaller larger => Many larger -> proxy smaller -> Many smaller
- Data.Diverse.Many.Internal: (\~.) :: forall smaller larger. Amend smaller larger => Many larger -> Many smaller -> Many larger
- Data.Diverse.Many.Internal: infixl 1 \~.
- Data.Diverse.Many.Internal: infixl 8 \^.
- 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.CaseNarrow smaller larger) (x : xs) [(Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)]
- Data.Diverse.Many.Internal: instance Data.Diverse.Reiterate.Reiterate (Data.Diverse.Many.Internal.CaseNarrow smaller larger) (x : xs)
- Data.Diverse.Many.Internal: instance Data.Diverse.Reiterate.ReiterateN (Data.Diverse.Many.Internal.CaseNarrowN indices smaller) n (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.CaseNarrowN indices smaller n) (x : xs) [(Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)]
- Data.Diverse.Many.Internal: narrow :: forall smaller larger. Narrow smaller larger => Many larger -> Many smaller
- Data.Diverse.Many.Internal: narrowN :: forall ns smaller larger proxy. NarrowN ns smaller larger => proxy ns -> Many larger -> Many smaller
- Data.Diverse.Many.Internal: type Narrow (smaller :: [Type]) (larger :: [Type]) = AFoldable (Collector (Via (CaseNarrow smaller larger)) larger) [(Key, WrappedAny)]
- Data.Diverse.Many.Internal: type NarrowN (ns :: [Nat]) (smaller :: [Type]) (larger :: [Type]) = (AFoldable (CollectorN (ViaN (CaseNarrowN ns smaller)) 0 larger) [(Key, WrappedAny)], smaller ~ KindsAtIndices ns larger, IsDistinct ns)
- Data.Diverse.PackageId: type PackageId = "data-diverse-0.2.1.0-HVzNZDHjJfaFyNLHjSdOFm"
+ Data.Diverse.Case: caseAny :: Case c xs r => c xs r -> Any -> 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: 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: item' :: forall x y xs. UniqueMember x xs => Lens (Many xs) (Many (Replace x y xs)) x y
+ Data.Diverse.Many: itemN' :: forall n x y xs proxy. MemberAt n x xs => proxy n -> Lens (Many xs) (Many (ReplaceIndex n y xs)) x y
+ 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: 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: replace' :: forall x y xs. UniqueMember x xs => Proxy x -> Many xs -> y -> Many (Replace x y xs)
+ Data.Diverse.Many: replaceN' :: forall n x y xs proxy. MemberAt n x xs => proxy n -> Many xs -> y -> Many (ReplaceIndex n y xs)
+ Data.Diverse.Many: select :: forall smaller larger. Select smaller larger => Many larger -> Many smaller
+ Data.Diverse.Many: selectN :: forall ns smaller larger proxy. SelectN ns smaller larger => proxy ns -> Many larger -> Many 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 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 Select (smaller :: [Type]) (larger :: [Type]) = AFoldable (Collector (Via (CaseSelect smaller larger)) larger) [(Key, 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.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: 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: 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 Data.Diverse.Reiterate.Reiterate (Data.Diverse.Many.Internal.CaseAmend' larger) (z : zs)
+ Data.Diverse.Many.Internal: instance Data.Diverse.Reiterate.Reiterate (Data.Diverse.Many.Internal.CaseSelect smaller larger) (x : xs)
+ Data.Diverse.Many.Internal: instance Data.Diverse.Reiterate.ReiterateN (Data.Diverse.Many.Internal.CaseAmendN' indices larger) n (z : zs)
+ Data.Diverse.Many.Internal: instance Data.Diverse.Reiterate.ReiterateN (Data.Diverse.Many.Internal.CaseSelectN indices smaller) n (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, 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, y) : zs) (Data.Diverse.Many.Internal.Key, Data.Diverse.Many.Internal.WrappedAny)
+ Data.Diverse.Many.Internal: item' :: forall x y xs. UniqueMember x xs => Lens (Many xs) (Many (Replace x y xs)) x y
+ Data.Diverse.Many.Internal: itemN' :: forall n x y xs proxy. MemberAt n x xs => proxy n -> Lens (Many xs) (Many (ReplaceIndex n y xs)) x y
+ 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: 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: replace' :: forall x y xs. UniqueMember x xs => Proxy x -> Many xs -> y -> Many (Replace x y xs)
+ Data.Diverse.Many.Internal: replaceN' :: forall n x y xs proxy. MemberAt n x xs => proxy n -> Many xs -> y -> Many (ReplaceIndex n y xs)
+ Data.Diverse.Many.Internal: select :: forall smaller larger. Select smaller larger => Many larger -> Many smaller
+ Data.Diverse.Many.Internal: selectN :: forall ns smaller larger proxy. SelectN ns smaller larger => proxy ns -> Many larger -> Many 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 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 Select (smaller :: [Type]) (larger :: [Type]) = AFoldable (Collector (Via (CaseSelect smaller larger)) larger) [(Key, 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.Type: type KindAtLabel (l :: k1) (xs :: [k2]) = KindAtLabelImpl l xs xs
+ Data.Diverse.Type: type Replace (x :: k) (y :: k) (xs :: [k]) = ReplaceImpl x y xs
+ Data.Diverse.Type: type ReplaceIndex (n :: Nat) (y :: k) (xs :: [k]) = ReplaceIndexImpl n xs n y xs
+ Data.Diverse.Type: type Replaces (xs :: [k]) (ys :: [k]) (zs :: [k]) = ReplacesImpl xs ys xs ys zs
+ Data.Diverse.Type: type ReplacesIndex (ns :: [Nat]) (ys :: [k]) (xs :: [k]) = ReplacesIndexImpl 0 ns ys xs
+ Data.Diverse.Type: type Zip (xs :: [k]) (ys :: [k]) = ZipImpl xs ys xs ys
- Data.Diverse.Case: case' :: Case c xs r => c xs r -> (Head xs -> r)
+ Data.Diverse.Case: case' :: Case c xs r => c xs r -> Head xs -> r
- Data.Diverse.Case: class Case c (xs :: [Type]) r
+ 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.Cases: cases :: SameLength fs (Distinct xs) => Many fs -> (Cases fs) xs r
+ Data.Diverse.Cases: cases :: SameLength fs (Nub xs) => Many fs -> (Cases fs) xs r
- Data.Diverse.Many: project :: forall smaller larger. (Narrow smaller larger, Amend smaller larger) => Lens' (Many larger) (Many smaller)
+ Data.Diverse.Many: project :: forall smaller larger. (Select smaller larger, Amend smaller larger) => Lens' (Many larger) (Many smaller)
- Data.Diverse.Many: projectN :: forall ns smaller larger proxy. (NarrowN ns smaller larger, AmendN ns smaller larger) => proxy ns -> Lens' (Many larger) (Many smaller)
+ Data.Diverse.Many: projectN :: forall ns smaller larger proxy. (SelectN ns smaller larger, AmendN ns smaller larger) => proxy ns -> Lens' (Many larger) (Many smaller)
- Data.Diverse.Many: replaceN :: forall n x xs proxy. MemberAt n x xs => proxy n -> Many xs -> x -> Many xs
+ Data.Diverse.Many: replaceN :: forall n x y xs proxy. MemberAt n x xs => proxy n -> Many xs -> y -> Many xs
- Data.Diverse.Many.Internal: project :: forall smaller larger. (Narrow smaller larger, Amend smaller larger) => Lens' (Many larger) (Many smaller)
+ Data.Diverse.Many.Internal: project :: forall smaller larger. (Select smaller larger, Amend smaller larger) => Lens' (Many larger) (Many smaller)
- Data.Diverse.Many.Internal: projectN :: forall ns smaller larger proxy. (NarrowN ns smaller larger, AmendN ns smaller larger) => proxy ns -> Lens' (Many larger) (Many smaller)
+ Data.Diverse.Many.Internal: projectN :: forall ns smaller larger proxy. (SelectN ns smaller larger, AmendN ns smaller larger) => proxy ns -> Lens' (Many larger) (Many smaller)
- Data.Diverse.Many.Internal: replaceN :: forall n x xs proxy. MemberAt n x xs => proxy n -> Many xs -> x -> Many xs
+ Data.Diverse.Many.Internal: replaceN :: forall n x y xs proxy. MemberAt n x xs => proxy n -> Many xs -> y -> Many xs

Files

data-diverse.cabal view
@@ -1,5 +1,5 @@ name:                data-diverse-version:             0.2.1.0+version:             0.3.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).@@ -29,13 +29,12 @@                        Data.Diverse.Emit                        Data.Diverse.Many                        Data.Diverse.Many.Internal-                       Data.Diverse.PackageId                        Data.Diverse.Reduce                        Data.Diverse.Reiterate                        Data.Diverse.Type-                       Data.Diverse.Type.Internal                        Data.Diverse.Which                        Data.Diverse.Which.Internal+  other-modules:       Data.Diverse.Type.Internal   build-depends:       base >= 4.7 && < 5                      , containers >= 0.5 && < 0.6                      , ghc-prim >= 0.5 && < 1@@ -52,9 +51,10 @@                        Data.Diverse.TypeSpec                        Data.Diverse.WhichSpec   build-depends:       base-                     , data-diverse+                     , data-diverse >= 0.2.1 && < 1                      , hspec >= 2 && < 3                      , lens >= 4 && < 5+                     , tagged >= 0.8.5 && < 1   ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall   default-language:    Haskell2010 
src/Data/Diverse/Case.hs view
@@ -1,12 +1,15 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-}  module Data.Diverse.Case where  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@@ -15,4 +18,9 @@ -- See "Data.Diverse.CaseTypeable" and "Data.Diverse.Cases". class Case c (xs :: [Type]) r where     -- | Return the handler/continuation when x is observed.-    case' :: c xs r -> (Head xs -> r)+    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/Cases.hs view
@@ -62,7 +62,7 @@ -- This function imposes additional @SameLength@ constraints than when using the 'Cases' constructor directly. -- It is better practice to use 'cases' to prevent programming confusion with dead code. -- However, the 'Cases' constructor is still exported to allow creating a master-of-all-'Case'.-cases :: SameLength fs (Distinct xs) => Many fs -> (Cases fs) xs r+cases :: SameLength fs (Nub xs) => Many fs -> (Cases fs) xs r cases = Cases  -----------------------------------------------
src/Data/Diverse/Many.hs view
@@ -29,32 +29,38 @@     -- * Single field     -- ** Getter for single field     , fetch-    , (.^.)     , fetchN     -- ** Setter for single field     , replace-    , (.~.)+    , replace'     , replaceN+    , replaceN'     -- ** Lens for a single field     , item+    , item'     , itemN+    , itemN'      -- * Multiple fields     -- ** Getter for multiple fields-    , Narrow-    , narrow-    , (\^.)-    , NarrowN-    , narrowN+    , Select+    , select+    , SelectN+    , selectN     -- ** Setter for multiple fields     , Amend     , amend-    , (\~.)+    , Amend'+    , amend'     , AmendN     , amendN+    , AmendN'+    , amendN'     -- ** Lens for multiple fields     , project+    , project'     , projectN+    , projectN'      -- * Destruction     -- ** By type
src/Data/Diverse/Many/Internal.hs view
@@ -46,32 +46,38 @@     -- * Single field     -- ** Getter for single field     , fetch-    , (.^.)     , fetchN     -- ** Setter for single field     , replace-    , (.~.)+    , replace'     , replaceN+    , replaceN'     -- ** Lens for a single field     , item+    , item'     , itemN+    , itemN'      -- * Multiple fields     -- ** Getter for multiple fields-    , Narrow-    , narrow-    , (\^.)-    , NarrowN-    , narrowN+    , Select+    , select+    , SelectN+    , selectN     -- ** Setter for multiple fields     , Amend     , amend-    , (\~.)+    , Amend'+    , amend'     , AmendN     , amendN+    , AmendN'+    , amendN'     -- ** Lens for multiple fields     , project+    , project'     , projectN+    , projectN'      -- * Destruction     -- ** By type@@ -93,7 +99,6 @@ import Data.Diverse.Case import Data.Diverse.Collector import Data.Diverse.Emit-import Data.Diverse.PackageId import Data.Diverse.Reiterate import Data.Diverse.Type import Data.Kind@@ -124,7 +129,7 @@ -- The following functions are available can be used to manipulate unique fields -- -- * getter/setter for single field: 'fetch' and 'replace'--- * getter/setter for multiple fields: 'narrow' and 'amend'+-- * getter/setter for multiple fields: 'select' and 'amend' -- * folds: 'forMany' or 'collect' -- -- These functions are type specified. This means labels are not required because the types themselves can be used to access the 'Many.@@ -133,7 +138,7 @@ -- For duplicate fields, Nat-indexed versions of the functions are available: -- -- * getter/setter for single field: 'fetchN' and 'replaceN'--- * getter/setter for multiple fields: 'narrowN' and 'amendN'+-- * getter/setter for multiple fields: 'selectN' and 'amendN' -- * folds: 'forManyN' or 'collectN' -- -- Encoding: The record is encoded as (Offset, Map Int Any).@@ -155,24 +160,16 @@  -- | A terminating 'G.Generic' instance encoded as a 'nul'. instance G.Generic (Many '[]) where-    type Rep (Many '[]) = G.D1 ('G.MetaData-                              "Many"-                              "Data.Diverse.Many.Internal"-                              PackageId-                              'False) G.U1-    from _ = {- G.D1 -} G.M1 {- G.U1 -} G.U1-    to (G.M1 G.U1) = nul+    type Rep (Many '[]) =  G.U1+    from _ = {- G.U1 -} G.U1+    to G.U1 = nul  -- | 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.D1 ('G.MetaData-                              "Many"-                              "Data.Diverse.Many.Internal"-                              PackageId-                              'False) ((G.Rec0 x) G.:*: (G.Rec0 (Many xs)))-    from r = {- G.D1 -} G.M1 (({- G.Rec0 -} G.K1 (front r)) G.:*: ({- G.Rec0 -} G.K1 (aft r)))-    to ({- G.D1 -} G.M1 (({- G.Rec0 -} G.K1 a) G.:*: ({- G.Rec0 -} G.K1 b))) = a ./ b+    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))+    to (({- G.Rec0 -} G.K1 a) G.:*: ({- G.Rec0 -} G.K1 b)) = a ./ b  ----------------------------------------------------------------------- @@ -410,18 +407,6 @@ fetch (Many o m) = unsafeCoerce (m M.! (Key (o + i)))   where i = fromInteger (natVal @(IndexOf x xs) Proxy) --- | infix version of 'fetch', with a extra proxy to carry the destination type.------ Mnemonic: Like 'Control.Lens.(^.)' but with an extra @.@ in front.------ @--- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nul'--- x '.^.' (Proxy \@Int) \`shouldBe` 5--- @-(.^.) :: forall x xs proxy. UniqueMember x xs => Many xs -> proxy x -> x-(.^.) v _ = fetch v-infixl 8 .^. -- like Control.Lens.(^.)- --------------------------------------------------  -- | Getter by index. Get the value of the field at index type-level Nat @n@@@ -443,17 +428,15 @@ replace (Many o m) v = Many o (M.insert (Key (o + i)) (unsafeCoerce v) m)   where i = fromInteger (natVal @(IndexOf x xs) Proxy) --- | infix version of 'replace'------ Mnemonic: Like a back to front 'Control.Lens.(.~)' with an extra @.@ in front.+-- | 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'--- (x '.~.' (6 :: Int)) \`shouldBe` (6 :: Int) './' False './' \'X' './' Just \'O' './' 'nul'+-- 'replace'' \@Int Proxy x (Just True) \`shouldBe` Just True './' False './' \'X' './' Just \'O' './' 'nul' -- @-(.~.) :: forall x xs. UniqueMember x xs => Many xs -> x -> Many xs-(.~.) = replace-infixl 1 .~. -- like Control.Lens.(.~)+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)  -------------------------------------------------- @@ -463,10 +446,15 @@ -- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nul' -- 'replaceN' \@0 Proxy x 7 `shouldBe` -- @-replaceN :: forall n x xs proxy. MemberAt n x xs => proxy n -> Many xs -> x -> Many xs+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)   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)+  where i = fromInteger (natVal p)+ -----------------------------------------------------------------------  -- | 'fetch' ('view' 'item') and 'replace' ('set' 'item') in 'Lens'' form.@@ -480,6 +468,11 @@ item = lens fetch replace {-# INLINE item #-} +-- | Polymorphic version of 'item'+item' :: forall x y xs. UniqueMember x xs => Lens (Many xs) (Many (Replace x y xs)) x y+item' = lens fetch (replace' @x @y Proxy)+{-# INLINE item' #-}+ -- | 'fetchN' ('view' 'item') and 'replaceN' ('set' 'item') in 'Lens'' form. -- -- @@@ -491,12 +484,20 @@ itemN p = lens (fetchN p) (replaceN p) {-# INLINE itemN #-} ++-- | Polymorphic version of 'itemN'+itemN' ::  forall n x y xs proxy. MemberAt n x xs => proxy n -> Lens (Many xs) (Many (ReplaceIndex n y xs)) x y+itemN' p = lens (fetchN p) (replaceN' @n @x @y p)+{-# INLINE itemN' #-}+ -----------------------------------------------------------------------  -- | Internal function for construction - do not expose! fromList' :: Ord k => [(k, WrappedAny)] -> M.Map k Any fromList' xs = M.fromList (coerce xs) +-----------------------------------------------------------------------+ -- | Wraps a 'Case' into an instance of 'Emit', 'reiterate'ing and feeding 'Case' with the value from the 'Many' -- and 'emit'ting the results. --@@ -514,11 +515,13 @@     reiterate (Via (c, xxs)) = Via (reiterate c, Partial.tail xxs)  instance (Case c (x ': xs) r) => Emit (Via c) (x ': xs) r where-    emit (Via (c, xxs)) = case' c (unsafeCoerce v)+    emit (Via (c, xxs)) = caseAny c v       where        -- use of front here is safe as we are guaranteed the length from the typelist        v = Partial.head xxs +-----------------------------------------------------------------------+ -- | Folds any 'Many', even with indistinct types. -- Given __distinct__ handlers for the fields in 'Many', create a 'Collector' -- of the results of running the handlers over the fields in 'Many'.@@ -559,7 +562,7 @@     reiterateN (ViaN (c, xxs)) = ViaN (reiterateN c, Partial.tail xxs)  instance (Case (c n) (x ': xs) r) => Emit (ViaN c n) (x ': xs) r where-    emit (ViaN (c, xxs)) = case' c (unsafeCoerce v)+    emit (ViaN (c, xxs)) = caseAny c v       where        -- use of front here is safe as we are guaranteed the length from the typelist        v = Partial.head xxs@@ -592,10 +595,10 @@  ----------------------------------------------------------------------- --- | A friendlier type constraint synomyn for 'narrow'-type Narrow (smaller :: [Type]) (larger :: [Type]) =+-- | A friendlier type constraint synomyn for 'select'+type Select (smaller :: [Type]) (larger :: [Type]) =     (AFoldable-        ( Collector (Via (CaseNarrow smaller larger)) larger) [(Key, WrappedAny)])+        ( Collector (Via (CaseSelect smaller larger)) larger) [(Key, WrappedAny)])  -- | Construct a 'Many' with a smaller number of fields than the original. -- Analogous to 'fetch' getter but for multiple fields.@@ -604,50 +607,38 @@ -- -- @ -- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nul'--- 'narrow' \@'[Bool, Char] x \`shouldBe` False './' \'X' './' 'nul'+-- 'select' \@'[Bool, Char] x \`shouldBe` False './' \'X' './' 'nul' -- @-narrow :: forall smaller larger. Narrow smaller larger => Many larger -> Many smaller-narrow t = Many 0 (fromList' xs')+select :: forall smaller larger. Select smaller larger => Many larger -> Many smaller+select t = Many 0 (fromList' xs')   where-    xs' = afoldr (++) [] (forMany (CaseNarrow @smaller @larger @larger) t)---- | infix version of 'narrow', with a extra proxy to carry the @smaller@ type.------ Mnemonic: Like 'Control.Lens.(^.)' but with an extra '\' (narrow to the right) in front.------ @--- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nul'--- x '\^.' (Proxy @'[Bool, Char]) \`shouldBe` False './' \'X' './' 'nul'--- @-(\^.) :: forall smaller larger proxy. Narrow smaller larger => Many larger -> proxy smaller -> Many smaller-(\^.) t _ = narrow t-infixl 8 \^. -- like Control.Lens.(^.)+    xs' = afoldr (++) [] (Collector (via (CaseSelect @smaller @larger @larger) t))  -- | For each type x in @larger@, generate the (k, v) in @smaller@ (if it exists)-data CaseNarrow (smaller :: [Type]) (larger :: [Type]) (xs :: [Type]) r = CaseNarrow+data CaseSelect (smaller :: [Type]) (larger :: [Type]) (xs :: [Type]) r = CaseSelect -instance Reiterate (CaseNarrow smaller larger) (x ': xs) where-    reiterate CaseNarrow = CaseNarrow+instance Reiterate (CaseSelect smaller larger) (x ': xs) where+    reiterate CaseSelect = CaseSelect  -- | 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 (CaseNarrow smaller larger) (x ': xs) [(Key, WrappedAny)] where-    case' _ v =+         Case (CaseSelect smaller larger) (x ': xs) [(Key, WrappedAny)] where+    caseAny _ v =         case i of             0 -> []-            i' -> [(Key (i' - 1), WrappedAny (unsafeCoerce v))]+            i' -> [(Key (i' - 1), WrappedAny v)]       where         i = fromInteger (natVal @(PositionOf x smaller) Proxy)  ----------------------------------------------------------------------- --- | A friendlier type constraint synomyn for 'narrowN'-type NarrowN (ns :: [Nat]) (smaller ::[Type]) (larger :: [Type]) =-    ( AFoldable (CollectorN (ViaN (CaseNarrowN ns smaller)) 0 larger) [(Key, WrappedAny)]+-- | 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)]     , smaller ~ KindsAtIndices ns larger     , IsDistinct ns) --- | A variation of 'narrow' which uses a Nat list @n@ to specify how to reorder the fields, where+-- | A variation of 'select' which uses a Nat list @n@ to specify how to reorder the fields, where -- -- @ -- indices[branch_idx] = tree_idx@@@ -658,28 +649,28 @@ -- -- @ -- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' (6 :: Int) './' Just \'A' './' 'nul'--- 'narrowN' (Proxy @'[5, 4, 0]) x \`shouldBe` Just \'A' './' (6 :: Int) './' (5 ::Int) './' 'nul'+-- 'selectN' (Proxy @'[5, 4, 0]) x \`shouldBe` Just \'A' './' (6 :: Int) './' (5 ::Int) './' 'nul' -- @-narrowN+selectN     :: forall ns smaller larger proxy.-       NarrowN ns smaller larger+       SelectN ns smaller larger     => proxy ns -> Many larger -> Many smaller-narrowN _ xs = Many 0 (fromList' xs')+selectN _ xs = Many 0 (fromList' xs')   where-    xs' = afoldr (++) [] (forManyN (CaseNarrowN @ns @smaller @0 @larger) xs)+    xs' = afoldr (++) [] (forManyN (CaseSelectN @ns @smaller @0 @larger) xs) -data CaseNarrowN (indices :: [Nat]) (smaller :: [Type]) (n :: Nat) (xs :: [Type]) r = CaseNarrowN+data CaseSelectN (indices :: [Nat]) (smaller :: [Type]) (n :: Nat) (xs :: [Type]) r = CaseSelectN -instance ReiterateN (CaseNarrowN indices smaller) n (x ': xs) where-    reiterateN CaseNarrowN = CaseNarrowN+instance ReiterateN (CaseSelectN indices smaller) n (x ': xs) where+    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 (CaseNarrowN indices smaller n) (x ': xs) [(Key, WrappedAny)] where-    case' _ v =+         Case (CaseSelectN indices smaller n) (x ': xs) [(Key, WrappedAny)] where+    caseAny _ v =         case i of             0 -> []-            i' -> [(Key (i' - 1), WrappedAny (unsafeCoerce v))]+            i' -> [(Key (i' - 1), WrappedAny v)]       where         i = fromInteger (natVal @(PositionOf n indices) Proxy) @@ -702,19 +693,6 @@   where     xs' = afoldr (:) [] (forMany (CaseAmend @larger @smaller lo) t) --- | infix version of 'amend'. Mnemonic: Like 'Control.Lens.(.~)' but with an extra '\' (narrow to the right) in front.------ Mnemonic: Like backwards 'Control.Lens.(^.)' but with an extra '\' (narrow to the right) in front.------ @--- let x = (5 :: Int) './' False './' \'X' './' Just \'O' './' 'nul'--- (x '\~.' (6 :: Int) './' Just \'P' './' 'nul') \`shouldBe`---     (6 :: Int) './' False './' \'X' './' Just \'P' './' 'nul'--- @-(\~.) :: forall smaller larger. Amend smaller larger => Many larger -> Many smaller -> Many larger-(\~.) = amend-infixl 1 \~. -- like Control.Lens.(.~)- newtype CaseAmend (larger :: [Type]) (xs :: [Type]) r = CaseAmend Int  instance Reiterate (CaseAmend larger) (x ': xs) where@@ -722,12 +700,38 @@  -- | 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-    case' (CaseAmend lo) v = (Key (lo + i), WrappedAny (unsafeCoerce v))+    caseAny (CaseAmend lo) v = (Key (lo + i), WrappedAny v)       where         i = fromInteger (natVal @(IndexOf x larger) Proxy)  ----------------------------------------------------------------------- +-- | A friendlier type constraint synomyn for 'amend''+type Amend' smaller smaller' larger = (AFoldable (Collector (Via (CaseAmend' larger)) (Zip smaller smaller')) (Key, WrappedAny), IsDistinct smaller)++amend' :: forall smaller smaller' larger. Amend' smaller smaller' larger+    => 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))++-- | 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)++newtype CaseAmend' (larger :: [Type]) (zs :: [Type]) r = CaseAmend' Int++instance Reiterate (CaseAmend' larger) (z ': zs) where+    reiterate (CaseAmend' lo) = CaseAmend' lo++-- | 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)+      where+        i = fromInteger (natVal @(IndexOf x larger) Proxy)++----------------------------------------------------------------------- -- | A friendlier type constraint synomyn for 'amendN' type AmendN ns smaller larger =     ( AFoldable (CollectorN (ViaN (CaseAmendN ns larger)) 0 smaller) (Key, WrappedAny)@@ -755,6 +759,8 @@   where     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@@ -763,16 +769,47 @@ -- | 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-    case' (CaseAmendN lo) v = (Key (lo + i), WrappedAny (unsafeCoerce v))+    caseAny (CaseAmendN lo) v = (Key (lo + i), WrappedAny v)       where         i = fromInteger (natVal @(KindAtIndex n indices) 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)+    , smaller ~ KindsAtIndices ns larger+    , IsDistinct ns)++-- | A polymorphic variation of 'amendN'+amendN' :: forall ns smaller smaller' larger proxy.+       (AmendN' ns smaller smaller' larger)+    => 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))++-- | 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)++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++-- | 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)+      where+        i = fromInteger (natVal @(KindAtIndex n indices) Proxy)+ ----------------------------------------------------------------------- --- | 'narrow' ('view' 'project') and 'amend' ('set' 'project') in 'Lens'' form.+-- | 'select' ('view' 'project') and 'amend' ('set' 'project') in 'Lens'' form. -- -- @--- 'project' = 'lens' 'narrow' 'amend'+-- 'project' = 'lens' 'select' 'amend' -- @ -- -- @@@ -783,15 +820,23 @@ -- @ project     :: forall smaller larger.-       (Narrow smaller larger, Amend smaller larger)+       (Select smaller larger, Amend smaller larger)     => Lens' (Many larger) (Many smaller)-project = lens narrow amend+project = lens select amend {-# INLINE project #-} --- | 'narrowN' ('view' 'projectN') and 'amendN' ('set' 'projectN') in 'Lens'' form.+-- | Polymorphic version of project'+project'+    :: forall smaller smaller' larger.+       (Select smaller larger, Amend' smaller smaller' larger)+    => Lens (Many larger) (Many (Replaces smaller smaller' larger)) (Many smaller) (Many smaller')+project' = lens select (amend' @smaller @smaller' Proxy)+{-# INLINE project' #-}++-- | 'selectN' ('view' 'projectN') and 'amendN' ('set' 'projectN') in 'Lens'' form. -- -- @--- 'projectN' = 'lens' 'narrowN' 'amendN'+-- 'projectN' = 'lens' 'selectN' 'amendN' -- @ -- -- @@@ -802,10 +847,18 @@ -- @ projectN     :: forall ns smaller larger proxy.-       (NarrowN ns smaller larger, AmendN ns smaller larger)+       (SelectN ns smaller larger, AmendN ns smaller larger)     => proxy ns -> Lens' (Many larger) (Many smaller)-projectN p = lens (narrowN p) (amendN p)+projectN p = lens (selectN p) (amendN p) {-# INLINE projectN #-}++-- | Polymorphic version of 'projectN'+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')+projectN' p = lens (selectN p) (amendN' p)+{-# INLINE projectN' #-}  ----------------------------------------------------------------------- 
− src/Data/Diverse/PackageId.hs
@@ -1,7 +0,0 @@-{-# LANGUAGE DataKinds #-}--module Data.Diverse.PackageId where---- | This is used for the Generic D1 metadata.--- NB. package id is obtained by running `stack exec ghc-pkg describe data-diverse`-type PackageId = "data-diverse-0.2.1.0-HVzNZDHjJfaFyNLHjSdOFm"
src/Data/Diverse/Type.hs view
@@ -35,9 +35,9 @@ type IsDistinct (xs :: [k]) = IsDistinctImpl xs xs  -- | Return the list of distinct types in a typelist-type family Distinct (xs :: [k]) :: [k] where-    Distinct '[] = '[]-    Distinct (x ': xs) = DistinctImpl xs x xs+type family Nub (xs :: [k]) :: [k] where+    Nub '[] = '[]+    Nub (x ': xs) = NubImpl xs x xs  -- | Ensures that @x@ only ever appears once in @xs@ type Unique (x :: k) (xs :: [k]) = UniqueImpl xs x xs@@ -53,6 +53,9 @@ -- | Get the type at an index 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+ -- | 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     KindAtPositionIs 0 x xs = ()@@ -63,33 +66,41 @@     KindsAtIndices '[] xs = '[]     KindsAtIndices (n ': ns) xs = KindAtIndex n xs ': KindsAtIndices ns xs --- | The typelist @xs@ without @x@. It is okay for @x@ not to exist in @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     Without x '[] = '[]-    Without x (x ': xs) = Without x xs+    Without x (x ': xs) = xs     Without x (y ': xs) = y ': Without x xs +-- | The typelist @xs@ with the first @x@ replaced by @y@. It is okay for @x@ not to exist in @xs@+type Replace (x :: k) (y :: k) (xs :: [k]) = ReplaceImpl x y xs++-- | The typelist @zs@ with the first @xs@ replaced by @ys@.+-- @xs@ must be the same size as @ys@+type Replaces (xs :: [k]) (ys :: [k]) (zs :: [k]) = ReplacesImpl xs ys xs ys zs+ -- | The typelist @xs@ without the type at Nat @n@. @n@ must be within bounds of @xs@ type WithoutIndex (n :: Nat) (xs :: [k]) = WithoutIndexImpl n xs n xs --- | Gets the ength of a typelist-type family Length (xs :: [k]) :: Nat where-    Length '[] = 0-    Length (x ': xs) = 1 + Length xs+-- | The typelist @xs@ without the type at Nat @n@ replaced by @y@. @n@ must be within bounds of @xs@+type ReplaceIndex (n :: Nat) (y :: k) (xs :: [k]) = ReplaceIndexImpl n xs n y xs +-- | The typelist @xs@ replaced by @ys@ at the indices @ns@. @ns@ and @ys@ must be the same length. @ns@ must be within bounds of @xs@+type ReplacesIndex (ns :: [Nat]) (ys :: [k]) (xs :: [k]) = ReplacesIndexImpl 0 ns ys xs+ -- | Get the typelist without the 'Head' type type family Tail (xs :: [k]) :: [k] where-    Tail '[] = TypeError ('Text "Cannot Tail an empty type list")+    Tail '[] = TypeError ('Text "Tail error: empty type list")     Tail (x ': xs) = xs  -- | Get the first type in a typelist type family Head (xs :: [k]) :: k where-    Head '[] = TypeError ('Text "Cannot Head an empty type list")+    Head '[] = TypeError ('Text "Head error: empty type list")     Head (x ': xs) = x  -- | Get the last type in a typelist type family Last (xs :: [k]) :: k where-    Last '[] = TypeError ('Text "Cannot Last an empty type list")+    Last '[] = TypeError ('Text "Last error: empty type list")     Last (x ': x' ': xs) = Last (x' ': xs)     Last '[x] = x @@ -108,6 +119,9 @@  -- | Returns the typelist without the 'Last' type type family Init (xs :: [k]) :: [k] where-    Init '[]  = TypeError ('Text "Cannot Init an empty type list")+    Init '[]  = TypeError ('Text "Init error: empty type list")     Init '[x] = '[]     Init (x ': xs) = x ': Init xs++-- | Takes two lists which must be the same length and returns a list of corresponding pairs.+type Zip (xs :: [k]) (ys :: [k]) = ZipImpl xs ys xs ys
src/Data/Diverse/Type/Internal.hs view
@@ -20,7 +20,7 @@ type family IndexOfImpl (ctx :: [k]) (x :: k) (xs :: [k]) :: Nat where    IndexOfImpl ctx x (x ': xs) = 0    IndexOfImpl ctx y (x ': xs) = 1 + IndexOfImpl ctx y xs-   IndexOfImpl ctx y '[] = TypeError ('Text "‘"+   IndexOfImpl ctx y '[] = TypeError ('Text "IndexOf error: ‘"                                       ':<>: 'ShowType y                                       ':<>: 'Text "’"                                       ':<>: 'Text " is not a member of "@@ -31,17 +31,17 @@ -- | Searches for y in ys -- if not found, than use y, and repeat search with next (y ': ys) in ctx -- else if found, then don't use y, then repeat search with next (y ': ys) in ctx-type family DistinctImpl (ctx :: [k]) (y :: k) (ys :: [k]) :: [k] where-    DistinctImpl '[] y '[] = y ': '[]-    DistinctImpl '[] y (y ': xs) = '[]-    DistinctImpl (x ': xs) y '[] = y ': DistinctImpl xs x xs-    DistinctImpl (x ': xs) y (y ': ys) = DistinctImpl xs x xs-    DistinctImpl ctx y (x ': xs) = DistinctImpl ctx y xs+type family NubImpl (ctx :: [k]) (y :: k) (ys :: [k]) :: [k] where+    NubImpl '[] y '[] = y ': '[]+    NubImpl '[] y (y ': xs) = '[]+    NubImpl (x ': xs) y '[] = y ': NubImpl xs x xs+    NubImpl (x ': xs) y (y ': ys) = NubImpl xs x xs+    NubImpl ctx y (x ': xs) = NubImpl ctx y xs  -- | 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 "‘"+    MissingImpl ctx x (x ': xs) = TypeError ('Text "Missing error: ‘"                                              ':<>: 'ShowType x                                              ':<>: 'Text "’"                                              ':<>: 'Text " is a duplicate in "@@ -63,7 +63,7 @@  -- | Indexed access into the list type family KindAtIndexImpl (orig :: Nat) (ctx :: [k]) (n :: Nat) (xs :: [k]) :: k where-    KindAtIndexImpl i ctx 0 '[] = TypeError ('Text "Index ‘"+    KindAtIndexImpl i ctx 0 '[] = TypeError ('Text "KindAtIndex error: Index ‘"                                        ':<>: 'ShowType i                                        ':<>: 'Text "’"                                        ':<>: 'Text " is out of bounds of "@@ -73,11 +73,23 @@     KindAtIndexImpl i ctx 0 (x ': xs) = x     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+    KindAtLabelImpl l ctx '[] = TypeError ('Text "KindAtLabel error: Label ‘"+                                       ':<>: 'ShowType l+                                       ':<>: 'Text "’"+                                       ':<>: 'Text " is not found in "+                                       ':<>: 'Text "‘"+                                       ':<>: 'ShowType ctx+                                       ':<>: 'Text "’")+    KindAtLabelImpl l ctx (tagged l x ': xs) = tagged l x+    KindAtLabelImpl l ctx (x ': xs) = KindAtLabelImpl l ctx xs+ -- | Ensures two typelists are the same length type family SameLengthImpl (ctx :: [k1]) (cty :: [k2]) (xs :: [k1]) (yx :: [k2]) :: Constraint where     SameLengthImpl as bs '[] '[] = ()     SameLengthImpl as bs (x ': xs) (y ': ys) = SameLengthImpl as bs xs ys-    SameLengthImpl as bs xs ys = TypeError ('Text "‘"+    SameLengthImpl as bs xs ys = TypeError ('Text "SameLength error: ‘"                                             ':<>: 'ShowType as                                             ':<>: 'Text "’"                                             ':<>: 'Text " is not the same length as "@@ -87,7 +99,7 @@  -- | The typelist @xs@ without the type at Nat @n@. @n@ must be within bounds of @xs@ type family WithoutIndexImpl (i :: Nat) (ctx :: [k]) (n :: Nat) (xs :: [k]) :: [k] where-    WithoutIndexImpl i ctx n '[] = TypeError ('Text "Index ‘"+    WithoutIndexImpl i ctx n '[] = TypeError ('Text "WithoutIndex error: Index ‘"                                        ':<>: 'ShowType i                                        ':<>: 'Text "’"                                        ':<>: 'Text " is out of bounds of "@@ -96,3 +108,68 @@                                        ':<>: 'Text "’")     WithoutIndexImpl i ctx 0 (x ': xs) = xs     WithoutIndexImpl i ctx n (x ': xs) = x ': WithoutIndexImpl i ctx (n - 1) xs++-- | The typelist @xs@ without the type at Nat @n@ replaced by @y@. @n@ must be within bounds of @xs@+type family ReplaceIndexImpl (i :: Nat) (ctx :: [k]) (n :: Nat) (y :: k) (xs :: [k]) :: [k] where+    ReplaceIndexImpl i ctx n y '[] = TypeError ('Text "ReplaceIndex error: Index ‘"+                                       ':<>: 'ShowType i+                                       ':<>: 'Text "’"+                                       ':<>: 'Text " is out of bounds of "+                                       ':<>: 'Text "‘"+                                       ':<>: 'ShowType ctx+                                       ':<>: 'Text "’")+    ReplaceIndexImpl i ctx 0 y (x ': xs) = y ': xs+    ReplaceIndexImpl i ctx n y (x ': xs) = x ': ReplaceIndexImpl i ctx (n - 1) y xs++-- | The typelist @xs@ with the first @x@ replaced by @y@. It is okay for @x@ not to exist in @xs@+type family ReplaceImpl (x :: k) (y :: k) (xs :: [k]) :: [k] where+    ReplaceImpl x y '[] = '[]+    ReplaceImpl x y (x ': xs) = y ': xs+    ReplaceImpl x y (z ': xs) = z ': ReplaceImpl x y xs++-- | The typelist @zs@ with the first @xs@ replaced by @ys@.+-- @xs@ must be the same size as @ys@+type family ReplacesImpl (xs' :: [k]) (ys' :: [k]) (xs :: [k]) (ys :: [k]) (zs :: [k]) :: [k] where+    ReplacesImpl xs' ys' xs ys '[] = '[]+    ReplacesImpl xs' ys' '[] '[] (z ': zs) = z ': ReplacesImpl xs' ys' xs' ys' zs+    ReplacesImpl xs' ys' (x ': xs) (y ': ys) (x ': zs) = y ': ReplacesImpl xs' ys' xs' ys' zs+    ReplacesImpl xs' ys' (x ': xs) (y ': ys) (z ': zs) = ReplacesImpl xs' ys' xs ys (z ': zs)+    ReplacesImpl xs' ys' xs ys zs = TypeError ('Text "Replaces error: ‘"+                                       ':<>: 'ShowType xs'+                                       ':<>: 'Text "’"+                                       ':<>: 'Text " must be the same size as "+                                       ':<>: 'Text "‘"+                                       ':<>: 'ShowType ys'+                                       ':<>: 'Text "’")++-- | The type @x@ replaced by an @y@ if an @n@ matches @i@.+type family ReplaceIfIndex (ns :: [Nat]) (ys :: [k]) (i :: Nat) (x :: k) :: k where+    ReplaceIfIndex '[] ys i x = x+    ReplaceIfIndex ns '[] i x = x+    ReplaceIfIndex (n ': ns) (y ': ys) n x = y+    ReplaceIfIndex (n ': ns) (y ': ys) i x = ReplaceIfIndex ns ys i x++-- | The typelist @xs@ replaced by @ys@ at the indices @ns@. @ns@ and @ys@ must be the same length. @ns@ must be within bounds of @xs@+type family ReplacesIndexImpl (i :: Nat) (ns :: [Nat]) (ys :: [k]) (xs :: [k]) :: [k] where+    ReplacesIndexImpl i ns ys '[] = '[]+    ReplacesIndexImpl i '[] '[] xs = xs+    ReplacesIndexImpl i ns ys (x ': xs) = ReplaceIfIndex ns ys i x ': ReplacesIndexImpl (i + 1) ns ys xs+    ReplacesIndexImpl i ns ys xs = TypeError ('Text "ReplacesIndex error: ‘"+                                       ':<>: 'ShowType ns+                                       ':<>: 'Text "’"+                                       ':<>: 'Text " must be the same size as "+                                       ':<>: 'Text "‘"+                                       ':<>: 'ShowType ys+                                       ':<>: 'Text "’")++-- | Zips up @xs@ and @ys@, which must be the same length+type family ZipImpl (xs' :: [k]) (ys' :: [k]) (xs :: [k]) (ys :: [k]) :: [k] where+    ZipImpl xs' ys' '[] '[] = '[]+    ZipImpl xs' ys' (x ': xs) (y ': ys) = (x, y) ': ZipImpl xs' ys' xs ys+    ZipImpl xs' ys' xs ys = TypeError ('Text "Zip error: ‘"+                              ':<>: 'ShowType xs'+                              ':<>: 'Text "’"+                              ':<>: 'Text " must be the same size as "+                              ':<>: 'Text "‘"+                              ':<>: 'ShowType ys'+                              ':<>: 'Text "’")
src/Data/Diverse/Which/Internal.hs view
@@ -64,7 +64,6 @@ import Data.Diverse.Case import Data.Diverse.Collector import Data.Diverse.Emit-import Data.Diverse.PackageId import Data.Diverse.Reduce import Data.Diverse.Reiterate import Data.Diverse.Type@@ -113,38 +112,25 @@ -- | A terminating 'G.Generic' instance for no types encoded as a 'impossible'. -- The 'G.C1' and 'G.S1' metadata are not encoded. instance G.Generic (Which '[]) where-  type Rep (Which '[]) = G.D1 ('G.MetaData-                            "Which"-                            "Data.Diverse.Which.Internal"-                            PackageId-                            'False) G.U1-  from _ = {- G.D1 -} G.M1 {- G.U1 -} G.U1-  to (G.M1 G.U1) = impossible+  type Rep (Which '[]) = G.U1+  from _ = {- G.U1 -} G.U1+  to G.U1 = impossible  -- | A terminating 'G.Generic' instance for one type encoded with 'pick''. -- The 'G.C1' and 'G.S1' metadata are not encoded. instance G.Generic (Which '[x]) where-    type Rep (Which '[x]) = G.D1 ('G.MetaData-                              "Which"-                              "Data.Diverse.Which.Internal"-                              PackageId-                              'False) (G.Rec0 x)-    from v = {- G.D1 -} G.M1 ({- G.Rec0 -} G.K1 (obvious v))-    to ({- G.D1 -} G.M1 ({- G.Rec0 -} G.K1 a)) = pickOnly a+    type Rep (Which '[x]) = G.Rec0 x+    from v = {- G.Rec0 -} G.K1 (obvious v)+    to ({- G.Rec0 -} G.K1 a) = pickOnly a  -- | A 'G.Generic' instance encoded as either the 'x' value ('G.:+:') or the 'diversify0'ed remaining 'Which xs'. -- The 'G.C1' and 'G.S1' metadata are not encoded. instance G.Generic (Which (x ': x' ': xs)) where-    type Rep (Which (x ': x' ': xs)) = G.D1 ('G.MetaData-                              "Which"-                              "Data.Diverse.Which.Internal"-                              PackageId-                              'False) ((G.Rec0 x) G.:+: (G.Rec0 (Which (x' ': xs))))-    from v = {- G.D1 -} G.M1 $-        case trial0 v of+    type Rep (Which (x ': x' ': xs)) = (G.Rec0 x) G.:+: (G.Rec0 (Which (x' ': xs)))+    from v = case trial0 v of             Right x -> G.L1 ({- G.Rec0 -} G.K1 x)             Left v' -> G.R1 ({- G.Rec0 -} G.K1 v')-    to ({- G.D1 -} G.M1 ({- G.Rec0 -} x)) = case x of+    to {- G.Rec0 -} x = case x of         G.L1 ({- G.Rec0 -} G.K1 a) -> pick0 a         G.R1 ({- G.Rec0 -} G.K1 v) -> diversify0 v @@ -327,7 +313,7 @@ -- | A variation of 'diversify' which uses a Nat list @n@ to specify how to reorder the fields, where -- -- @--- indices[branch_idx] = tree_idx@+-- indices[branch_idx] = tree_idx -- @ -- -- This variation allows @tree@ to contain duplicate types with @branch@ since@@ -399,7 +385,7 @@ -- | A limited variation of 'reinterpret' which uses a Nat list @n@ to specify how to reorder the fields, where -- -- @--- indices[branch_idx] = tree_idx@+-- indices[branch_idx] = tree_idx -- @ -- -- This variation allows @tree@ to contain duplicate types with @branch@
test/Data/Diverse/ManySpec.hs view
@@ -11,6 +11,7 @@ import Control.Lens import Data.Diverse import Data.Typeable+import Data.Tagged import Test.Hspec  -- `main` is here so that this module can be run from GHCi on its own.  It is@@ -18,6 +19,9 @@ main :: IO () main = hspec spec +data Foo+data Bar+ spec :: Spec spec = do     describe "Many" $ do@@ -91,13 +95,9 @@         it "has getter for unique fields using 'fetch'" $ do             let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul             fetch @Int x `shouldBe` 5-            x .^. (Proxy @Int) `shouldBe` 5             fetch @Bool x `shouldBe` False-            x .^. (Proxy @Bool) `shouldBe` False             fetch @Char x `shouldBe` 'X'-            x .^. (Proxy @Char) `shouldBe` 'X'             fetch @(Maybe Char) x `shouldBe` Just 'O'-            x .^. (Proxy @(Maybe Char))`shouldBe` Just 'O'          it "has getter for for unique fields using 'fetchN'" $ do             let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul@@ -118,24 +118,28 @@         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             fetch @Bool x `shouldBe` False-            x .^. (Proxy @Bool) `shouldBe` False             fetch @Char x `shouldBe` 'X'-            x .^. (Proxy @Char) `shouldBe` 'X' +        it "can 'fetch' usng tagged labels" $ do+            let y = (5 :: Int) ./ False ./ Tagged @Foo 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            fetch @(Tagged Foo _) y `shouldBe` Tagged @Foo 'X'+         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-            (x .~. (6 :: Int)) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul             replace x True `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nul-            (x .~. True) `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nul             replace x 'O' `shouldBe` (5 :: Int) ./ False ./ 'O' ./ Just 'O' ./ nul-            (x .~. 'O') `shouldBe` (5 :: Int) ./ False ./ 'O' ./ Just 'O' ./ nul             replace x (Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul-            (x .~. (Just 'P')) `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul +        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+         it "has setter for unique fields using 'replaceN'" $ do             let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-            replaceN @0 Proxy x 7 `shouldBe`+            replaceN @0 Proxy x (7 :: Int) `shouldBe`                 (7 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul             replaceN @1 Proxy x True `shouldBe`                 (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nul@@ -144,9 +148,19 @@             replaceN @3 Proxy x (Just 'P') `shouldBe`                 (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul +        it "has polymorphic setter using 'replaceN''" $ do+            let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul+            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+            replaceN' @1 Proxy y 'Y' `shouldBe`+                (5 :: Int) ./ 'Y' ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul+            replaceN' @5 Proxy y 'Y' `shouldBe`+                (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ 'Y' ./ nul+         it "has setter for duplicate fields using 'replaceN'" $ do             let y = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            replaceN @0 Proxy y 7 `shouldBe`+            replaceN @0 Proxy y (7 :: Int) `shouldBe`                 (7 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul             replaceN @1 Proxy y True `shouldBe`                 (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul@@ -154,7 +168,7 @@                 (5 :: Int) ./ False ./ 'Y' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul             replaceN @3 Proxy y (Just 'P') `shouldBe`                 (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ (6 :: Int) ./ Just 'A' ./ nul-            replaceN @4 Proxy y 8 `shouldBe`+            replaceN @4 Proxy y (8 :: Int) `shouldBe`                 (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (8 :: Int) ./ Just 'A' ./ nul             replaceN @5 Proxy y (Just 'B') `shouldBe`                 (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'B' ./ nul@@ -166,6 +180,16 @@             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+         it "has getter/setter lens using 'item'" $ do             let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul             x ^. item @Int `shouldBe` 5@@ -173,10 +197,16 @@             x ^. item @Bool `shouldBe` False             (x & item @Bool .~ True) `shouldBe` (5 :: Int) ./ True ./ 'X' ./ Just 'O' ./ nul             x ^. item @Char `shouldBe` 'X'-            (x & item @Char .~ 'O') `shouldBe` (5 :: Int) ./ False ./ 'O' ./ Just 'O' ./ nul             x ^. item @(Maybe Char) `shouldBe` Just 'O'-            (x & item @(Maybe Char) .~ Just 'P') `shouldBe` (5 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul +        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+         it "has 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) `shouldBe` 5@@ -192,43 +222,58 @@             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 -        it "has getter for multiple fields using 'narrow'" $ do+        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++        it "has getter for multiple fields using 'select'" $ do             let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-            narrow @'[Int, Maybe Char] x `shouldBe` (5 :: Int) ./ Just 'O' ./ nul-            x \^. (Proxy @'[Int, Maybe Char]) `shouldBe` (5 :: Int) ./ Just 'O' ./ nul+            select @'[Int, Maybe Char] x `shouldBe` (5 :: Int) ./ Just 'O' ./ nul -        it "can reorder fields using 'narrow' or 'narrowN'" $ do+        it "can reorder fields using 'select' or 'selectN'" $ do             let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nul-            narrow @'[Bool, Int, Maybe Char] x `shouldBe` False ./ (5 :: Int) ./ 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-            narrowN (Proxy @'[5, 4, 0, 1, 3, 2]) y `shouldBe`+            selectN (Proxy @'[5, 4, 0, 1, 3, 2]) y `shouldBe`                 Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ False ./ Just 'O' ./ 'X' ./ nul -        it "has getter for multiple fields with duplicates using 'narrowN'" $ do+        it "has getter for multiple fields with duplicates using 'selectN'" $ do             let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul-            narrowN (Proxy @'[5, 4, 0]) x `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nul+            selectN (Proxy @'[5, 4, 0]) x `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nul -        it "can't narrow into types from indistinct fields" $ do+        it "can't select into types from indistinct fields" $ do             let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul             -- Compile error: Int is a duplicate-            -- narrow @[Bool, Char, Int] x `shouldBe` False ./ 'X' ./ (5 :: Int) ./ nul-            x `shouldBe` x+            -- select @[Bool, Char, Int] x `shouldBe` False ./ 'X' ./ (5 :: Int) ./ nul+            x `shouldBe`  x -        it "with duplicate fields has getter for multiple unique fields 'narrow'" $ do+        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-            narrow @'[Bool, Char] x `shouldBe` False ./ 'X' ./ nul-            x \^. (Proxy @'[Bool, Char]) `shouldBe` False ./ 'X' ./ nul+            select @'[Bool, Char] x `shouldBe` False ./ 'X' ./ nul          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-            (x \~. (6 :: Int) ./ Just 'P' ./ nul) `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul +        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+         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 +        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+         it "can't amend into types from indistinct fields" $ do             let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul             -- Compile error: Int is a duplicate@@ -247,11 +292,21 @@             (x & (project @'[Int, Maybe Char]) .~ ((6 :: Int) ./ Just 'P' ./ nul)) `shouldBe`                 (6 :: Int) ./ False ./ 'X' ./ Just 'P' ./ nul +        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+         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++        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          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