-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Extensible records and polymorphic variants. -- -- Data.Diverse.Many is an extensible record for any size encoded -- efficiently as (Seq Any). Data.Diverse.Which is a polymorphic -- variant of possibilities encoded as (Int, Any). Provides getters, -- setters, projection, injection, folds, and catamorphisms; accessed by -- type, index or label. Refer to ManySpec.hs and -- WhichSpec.hs for example usages. Iso, Lens and Prisms are -- provided in data-diverse-lens @package data-diverse @version 1.2.0.2 module Data.Diverse.TypeLevel.Internal -- | Get the first position of a type (indexed by 1) Will return 0 if -- x doesn't exists in xs. -- | Get the first index of a type from a list -- | 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 -- | Errors if a type exists in a typelist -- | Errors if a label exists in a typelist -- | Ensures that the type list contain unique types. Not implemented as -- (xs ~ Nub xs) for better type error messages. -- | Ensures that x only ever appears once in xs -- | Ensures that the label in tagged label v only ever -- appears once in xs. -- | Indexed access into the list -- | Labelled access into the list -- | Ensures two typelists are the same length -- | The typelist xs without the type at Nat n. -- n must be within bounds of xs -- | The typelist xs without the type at Nat n replaced -- by y. n must be within bounds of xs -- | The typelist xs with the first x replaced by -- y. It is okay for x not to exist in xs -- | The typelist zs with the first xs replaced by -- ys. xs must be the same size as ys -- | The type x replaced by an y if an n matches -- i. -- | 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 -- | Zips up xs and ys, which must be the same length module Data.Diverse.TypeLevel -- | 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)) -- | Every x in xs is a `UniqueMember x ys` -- | 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)) -- | 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) -- | Ensures that x is a member of xs at n if it -- exists, and that natVal can be used. type MaybeMemberAt n x xs = (KnownNat n, KindAtPositionIs n x xs) -- | Snoc x to end of xs if x doesn't already -- exist in xs -- | For each y in ys, snocs them to end of xs -- if y doesn't already exist in xs -- | Ensures x is a unique member in xs iff it exists in -- ys -- | Ensures that the type list contain unique types type IsDistinct (xs :: [k]) = IsDistinctImpl xs xs -- | Return the list of distinct types in a typelist -- | 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 UniqueLabels -- | 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 -- | Get the first index of a type (Indexed by 1) Will return 0 if x -- doesn't exists in xs. type PositionOf (x :: k) (xs :: [k]) = PositionOfImpl 0 x xs -- | 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 :: [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 -- | Get the types at an list of index -- | Get the types with labels ls from xs -- | The typelist xs without first x. It is okay for -- x not to exist in 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 RemoveIndex (n :: Nat) (xs :: [k]) = RemoveIndexImpl n xs n 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 -- | Returns the typelist up to and excluding x. If x -- doesn't exist, then the original xs is returned. -- | Returns the typelist up to and including x. If x -- doesn't exist, then the original xs is returned. -- | Returns the typelist after and excluding x. If x -- doesn't exist, then an empty '[] is returned. -- | Returns the typelist after and including x. If x -- doesn't exist, then an empty '[] is returned. -- | Returns the typelist before (and exluding) index n. If -- n is larger then the xs size, then the original -- xs is returned. -- | Returns the typelist up to (and including) index n. If -- n is larger then the xs size, then the original -- xs is returned. -- | Returns the typelist after (and exluding) index n. If -- n is larger then the xs size, then an empty '[] is -- returned. -- | Returns the typelist from (and including) index n. If -- n is larger then the xs size, then an empty '[] is -- returned. -- | Get the typelist without the Head type -- | Get the first type in a typelist -- | Ensures two typelists are the same length type SameLength (xs :: [k1]) (ys :: [k2]) = SameLengthImpl xs ys xs ys -- | Set complement. Returns the set of things in xs that are not -- in ys. -- | Returns a xs appended with ys -- | Returns the typelist without the Last type -- | 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 -- | The result from evaluating a Case with a type from a -- typelist. -- | Return a list of results from applying CaseResult to every type -- in the xs typelist. -- | Tests if all the types in a typelist satisfy a constraint module Data.Diverse.Reiterate -- | Allows iterating over the types in a typelist class Reiterate c (xs :: [Type]) -- | Return the next iteration without the Head type x in (x ': xs) reiterate :: Reiterate c xs => c xs -> c (Tail xs) -- | Allows iterating over the types in a typelist, whilst also -- incrementing an Nat index class ReiterateN c (n :: Nat) (xs :: [Type]) -- | Return the next iteration without the Head type x in (x ': xs) reiterateN :: ReiterateN c n xs => c n xs -> c (n + 1) (Tail xs) module Data.Diverse.Reduce -- | Convert something v into r using handlers. This -- class is required in order to step through all the different types in -- a variant. class Reduce v handler reduce :: Reduce v handler => handler -> v -> Reduced handler module Data.Diverse.Case -- | This class allows defining handlers that can handle the Head -- type in the xs typelist. In conjunction with -- Reiterate, you can define handlers that can handle all the -- types in the xs typelist. -- -- See Data.Diverse.CaseFunc and Data.Diverse.Cases. class Case c (xs :: [Type]) -- | Return the handler/continuation when x is observed. case' :: Case c xs => c xs -> Head xs -> CaseResult c (Head xs) module Data.Diverse.CaseFunc -- | This handler stores a polymorphic function that returns a different -- type. -- --
-- let y = pick (5 :: Int) :: Which '[Int, Bool] -- switch y (CaseFunc @Typeable (show . typeRep . (pure @Proxy))) `shouldBe` Int ---- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul -- afoldr (:) [] (forMany (CaseFunc @Typeable (show . typeRep . (pure @Proxy))) x) `shouldBe` -- ["Int", "Bool", "Char", "Maybe Char", "Int", "Maybe Char"] --newtype CaseFunc (k :: Type -> Constraint) r (xs :: [Type]) CaseFunc :: (forall x. k x => x -> r) -> CaseFunc r -- | This handler stores a polymorphic function that doesn't change the -- type. -- --
-- let x = (5 :: Int) ./ (6 :: Int8) ./ (7 :: Int16) ./ (8 :: Int32) ./ nil -- y = (15 :: Int) ./ (16 :: Int8) ./ (17 :: Int16) ./ (18 :: Int32) ./ nil -- afmap (CaseFunc' @Num (+10)) x `shouldBe` y --newtype CaseFunc' (k :: Type -> Constraint) (xs :: [Type]) CaseFunc' :: (forall x. k x => x -> x) -> CaseFunc' instance Data.Diverse.Reiterate.Reiterate (Data.Diverse.CaseFunc.CaseFunc k r) xs instance k x => Data.Diverse.Case.Case (Data.Diverse.CaseFunc.CaseFunc k r) (x : xs) instance Data.Diverse.Reiterate.Reiterate (Data.Diverse.CaseFunc.CaseFunc' k) xs instance k x => Data.Diverse.Case.Case (Data.Diverse.CaseFunc.CaseFunc' k) (x : xs) module Data.Diverse.Which.Internal -- | A Which is an anonymous sum type (also known as a polymorphic -- variant, or co-record) which can only contain one of the types in the -- typelist. This is essentially a typed version of Dynamic. -- -- The following functions are available can be used to manipulate unique -- types in the typelist -- --
-- pick 'A' @_ @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String] --pick :: forall x xs. UniqueMember x xs => x -> Which xs -- | A variation of pick into a Which where x is the -- first type. -- --
-- pick0 'A' :: Which '[Char, Int, Bool] --pick0 :: x -> Which (x : xs) -- | A variation of pick into a Which of a single type. -- --
-- pickOnly 'A' :: Which '[Char] --pickOnly :: x -> Which '[x] -- | 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 proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> x -> Which xs -- | Lift a value into a Which of possibly other (possibley -- indistinct) types, where the value is the n-th type. -- --
-- pickN (Proxy @4) (5 :: Int) :: Which '[Bool, Int, Char, Bool, Int, Char] --pickN :: forall n xs proxy x. MemberAt n x xs => proxy n -> x -> Which xs -- | It is obvious what value is inside a Which of one type. -- --
-- let x = pick' 'A' :: Which '[Char] -- obvious x `shouldBe` 'A' --obvious :: Which '[a] -> a -- | trial a type in a Which and Either get the -- Right value or the Left-over possibilities. -- --
-- let x = pick 'A' @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String] -- trial @Char x `shouldBe` Right 'A' -- trial @Int x `shouldBe` Left (pick 'A') :: Which '[Bool, Char, Maybe String] --trial :: forall x xs. (UniqueMember x xs) => Which xs -> Either (Which (Remove x xs)) x -- | Variation of trial which returns a Maybe trial' :: forall x xs. (UniqueMember x xs) => Which xs -> Maybe x -- | A variation of a Which trial which trials the -- first type in the type list. -- --
-- let x = pick 'A' @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String] -- trial0 x `shouldBe` Left (pick 'A') :: Which '[Bool, Char, Maybe String] --trial0 :: forall x xs. Which (x : xs) -> Either (Which xs) x -- | Variation of trial0 which returns a Maybe trial0' :: forall x xs. Which (x : xs) -> Maybe x -- | 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 proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Which xs -> Either (Which (Remove x xs)) x -- | Variation of trialL which returns a Maybe trialL' :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Which xs -> Maybe x -- | trialN the n-th type of a Which, and get Either -- the Right value or the Left-over possibilities. -- --
-- let x = pick 'A' @_ @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String] -- trialN @_ @1 Proxy x `shouldBe` Left (pick 'A') :: Which '[Int, Char, Maybe String] --trialN :: forall n xs proxy x. (MemberAt n x xs) => proxy n -> Which xs -> Either (Which (RemoveIndex n xs)) x -- | Variation of trialN which returns a Maybe trialN' :: forall n xs proxy x. (MemberAt n x xs) => proxy n -> Which xs -> Maybe x -- | A friendlier constraint synonym for diversify. type Diversify (branch :: [Type]) (tree :: [Type]) = Reduce (Which branch) (Switcher (CaseDiversify branch tree) (Which tree) branch) -- | Convert a Which to another Which that may include other -- possibilities. That is, branch is equal or is a subset of -- tree. -- -- This can also be used to rearrange the order of the types in the -- Which. -- -- It is a compile error if tree has duplicate types with -- branch. -- -- NB. Use TypeApplications with _ to specify tree@. -- --
-- let a = pick' (5 :: Int) :: Which '[Int] -- b = diversify @_ @[Int, Bool] a :: Which '[Int, Bool] -- c = diversify @_ @[Bool, Int] b :: Which '[Bool, Int] --diversify :: forall branch tree. Diversify branch tree => Which branch -> Which tree -- | A restricted version of diversify which only rearranges the -- types diversify' :: forall branch tree. (Diversify branch tree, SameLength branch tree) => Which branch -> Which tree -- | A simple version of diversify which add another type to the -- front of the typelist. diversify0 :: forall x xs. Which xs -> Which (x : xs) -- | A variation of diversify where branchis 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'' (CaseFunc @Typeable (show . typeRep . (pure @Proxy))) `shouldBe` "Tagged * Bar Int" --diversifyL :: forall ls branch tree proxy. (Diversify branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) => proxy ls -> Which branch -> Which tree -- | A friendlier constraint synonym for diversifyN. type DiversifyN (indices :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (Reduce (Which branch) (SwitcherN (CaseDiversifyN indices) (Which tree) 0 branch), KindsAtIndices indices tree ~ branch) -- | A variation of diversify which uses a Nat list indices -- to specify how to reorder the fields, where -- --
-- indices[branch_idx] = tree_idx ---- -- This variation allows tree to contain duplicate types with -- branch since the mapping is specified by indicies. -- --
-- let y = pickOnly (5 :: Int) -- y' = diversifyN @'[0] @_ @[Int, Bool] Proxy y -- y'' = diversifyN @[1,0] @_ @[Bool, Int] Proxy y' -- switch y'' (CaseFunc @Typeable (show . typeRep . (pure @Proxy))) `shouldBe` "Int" --diversifyN :: forall indices branch tree proxy. (DiversifyN indices branch tree) => proxy indices -> Which branch -> Which tree -- | A friendlier constraint synonym for reinterpret. type Reinterpret branch tree = Reduce (Which tree) (Switcher (CaseReinterpret branch tree) (Either (Which (Complement tree branch)) (Which branch)) tree) -- | Convert a Which into possibly another Which with a -- totally different typelist. Returns either a Which with the -- Right value, or a Which with the Leftover -- compliment types. -- -- It is a compile error if branch or compliment has -- duplicate types with tree. -- -- NB. forall used to specify branch first, so TypeApplications -- can be used to specify branch first. -- --
-- let a = pick @[Int, Char, Bool] (5 :: Int) :: Which '[Int, Char, Bool] -- let b = reinterpret [String, Char] y -- b `shouldBe` Left (pick (5 :: Int)) :: Which '[Int, Bool] -- let c = reinterpret [String, Int] a -- c `shouldBe` Right (pick (5 :: Int)) :: Which '[String, Int] --reinterpret :: forall branch tree. Reinterpret branch tree => Which tree -> Either (Which (Complement tree branch)) (Which branch) -- | A friendlier constraint synonym for reinterpret'. type Reinterpret' branch tree = Reduce (Which tree) (Switcher (CaseReinterpret' branch tree) (Maybe (Which branch)) tree) -- | Variation of reinterpret which returns a Maybe. reinterpret' :: forall branch tree. Reinterpret' branch tree => Which tree -> Maybe (Which branch) -- | 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) -- | Variation of reinterpretL which returns a Maybe. reinterpretL' :: forall ls branch tree proxy. (Reinterpret' branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) => proxy ls -> Which tree -> Maybe (Which branch) -- | A friendlier constraint synonym for reinterpretN. type ReinterpretN' (indices :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (Reduce (Which tree) (SwitcherN (CaseReinterpretN' indices) (Maybe (Which branch)) 0 tree), KindsAtIndices indices tree ~ branch) -- | A limited variation of reinterpret which uses a Nat list -- n to specify how to reorder the fields, where -- --
-- indices[branch_idx] = tree_idx ---- -- This variation allows tree to contain duplicate types with -- branch since the mapping is specified by indicies. -- -- However, unlike reinterpert, in this variation, -- branch must be a subset of tree instead of any -- arbitrary Which. Also it returns a Maybe instead of Either. -- -- This is so that the same indices can be used in -- narrowN. reinterpretN' :: forall (indices :: [Nat]) branch tree proxy. (ReinterpretN' indices branch tree) => proxy indices -> Which tree -> Maybe (Which branch) -- | A friendlier constraint synonym for switch. type Switch c r xs = Reduce (Which xs) (Switcher c r xs) -- | Switcher is an instance of Reduce for which -- reiterates through the possibilities in a Which, -- delegating handling to Case, ensuring termination when -- Which only contains one type. newtype Switcher c r (xs :: [Type]) Switcher :: (c r xs) -> Switcher c r -- | Catamorphism for Which. This is equivalent to flip -- switch. which :: Switch c r xs => c r xs -> Which xs -> r -- | A switch/case statement for Which. This is equivalent to -- flip which -- -- Use Case instances like Cases to apply a Which of -- functions to a variant of values. -- --
-- let y = pick (5 :: Int) :: Which '[Int, Bool] -- switch y ( -- cases (show @Bool -- ./ show @Int -- ./ nil)) `shouldBe` "5" ---- -- Or CaseFunc @Typeable to apply a polymorphic function -- that work on all Typeables. -- --
-- let y = pick (5 :: Int) :: Which '[Int, Bool] -- switch y (CaseFunc @Typeable (show . typeRep . (pure @Proxy))) `shouldBe` Int ---- -- Or you may use your own custom instance of Case. switch :: Switch c r xs => Which xs -> c r xs -> r -- | A friendlier constraint synonym for switch. type SwitchN c r n xs = Reduce (Which xs) (SwitcherN c r n xs) -- | SwitcherN is a variation of Switcher which -- reiterateNs through the possibilities in a Which, -- delegating work to CaseN, ensuring termination when -- Which only contains one type. newtype SwitcherN c r (n :: Nat) (xs :: [Type]) SwitcherN :: (c r n xs) -> SwitcherN c r -- | Catamorphism for Which. This is equivalent to flip -- switchN. whichN :: SwitchN c r n xs => c r n xs -> Which xs -> r -- | A switch/case statement for Which. This is equivalent to -- flip whichN -- -- Use Case instances like CasesN to apply a Which -- of functions to a variant of values in index order. -- --
-- let y = pickN @0 Proxy (5 :: Int) :: Which '[Int, Bool, Bool, Int] -- switchN y ( -- casesN (show @Int -- ./ show @Bool -- ./ show @Bool -- ./ show @Int -- ./ nil)) `shouldBe` "5" ---- -- Or you may use your own custom instance of Case. switchN :: SwitchN c r n xs => Which xs -> c r n xs -> r instance Control.DeepSeq.NFData (Data.Diverse.Which.Internal.Which '[]) instance Control.DeepSeq.NFData x => Control.DeepSeq.NFData (Data.Diverse.Which.Internal.Which '[x]) instance (Control.DeepSeq.NFData x, Control.DeepSeq.NFData (Data.Diverse.Which.Internal.Which (x' : xs))) => Control.DeepSeq.NFData (Data.Diverse.Which.Internal.Which (x : x' : xs)) instance GHC.Generics.Generic (Data.Diverse.Which.Internal.Which '[]) instance GHC.Generics.Generic (Data.Diverse.Which.Internal.Which '[x]) instance GHC.Generics.Generic (Data.Diverse.Which.Internal.Which (x : x' : xs)) instance Data.Semigroup.Semigroup (Data.Diverse.Which.Internal.Which '[]) instance Data.Diverse.Reiterate.Reiterate (Data.Diverse.Which.Internal.CaseDiversify r branch tree) branch' instance (Data.Diverse.TypeLevel.UniqueMember x tree, Data.Diverse.TypeLevel.Unique x branch) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseDiversify branch tree (Data.Diverse.Which.Internal.Which tree)) (x : branch') instance Data.Diverse.Reiterate.ReiterateN (Data.Diverse.Which.Internal.CaseDiversifyN indices r) n branch' instance Data.Diverse.TypeLevel.MemberAt (Data.Diverse.TypeLevel.KindAtIndex n indices) x tree => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseDiversifyN indices (Data.Diverse.Which.Internal.Which tree) n) (x : branch') instance Data.Diverse.Reiterate.Reiterate (Data.Diverse.Which.Internal.CaseReinterpret branch tree r) tree' instance (Data.Diverse.TypeLevel.MaybeUniqueMember x branch, comp ~ Data.Diverse.TypeLevel.Complement tree branch, Data.Diverse.TypeLevel.MaybeUniqueMember x comp, Data.Diverse.TypeLevel.Unique x tree) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseReinterpret branch tree (Data.Either.Either (Data.Diverse.Which.Internal.Which comp) (Data.Diverse.Which.Internal.Which branch))) (x : tree') instance Data.Diverse.Reiterate.Reiterate (Data.Diverse.Which.Internal.CaseReinterpret' branch tree r) tree' instance (Data.Diverse.TypeLevel.MaybeUniqueMember x branch, comp ~ Data.Diverse.TypeLevel.Complement tree branch, Data.Diverse.TypeLevel.Unique x tree) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseReinterpret' branch tree (GHC.Base.Maybe (Data.Diverse.Which.Internal.Which branch))) (x : tree') instance Data.Diverse.Reiterate.ReiterateN (Data.Diverse.Which.Internal.CaseReinterpretN' indices r) n tree' instance (Data.Diverse.TypeLevel.MaybeMemberAt n' x branch, n' ~ Data.Diverse.TypeLevel.PositionOf n indices) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseReinterpretN' indices (GHC.Base.Maybe (Data.Diverse.Which.Internal.Which branch)) n) (x : tree) instance (Data.Diverse.Case.Case (c r) (x : x' : xs), Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x' : xs)) (Data.Diverse.Which.Internal.Switcher c r (x' : xs)), Data.Diverse.Reiterate.Reiterate (c r) (x : x' : xs), r ~ Data.Diverse.TypeLevel.CaseResult (c r) x) => Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : x' : xs)) (Data.Diverse.Which.Internal.Switcher c r (x : x' : xs)) instance (Data.Diverse.Case.Case (c r) '[x], r ~ Data.Diverse.TypeLevel.CaseResult (c r) x) => Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which '[x]) (Data.Diverse.Which.Internal.Switcher c r '[x]) instance Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which '[]) (Data.Diverse.Which.Internal.Switcher c r '[]) instance (Data.Diverse.Case.Case (c r n) (x : x' : xs), Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x' : xs)) (Data.Diverse.Which.Internal.SwitcherN c r (n GHC.TypeLits.+ 1) (x' : xs)), Data.Diverse.Reiterate.ReiterateN (c r) n (x : x' : xs), r ~ Data.Diverse.TypeLevel.CaseResult (c r n) x) => Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : x' : xs)) (Data.Diverse.Which.Internal.SwitcherN c r n (x : x' : xs)) instance (Data.Diverse.Case.Case (c r n) '[x], r ~ Data.Diverse.TypeLevel.CaseResult (c r n) x) => Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which '[x]) (Data.Diverse.Which.Internal.SwitcherN c r n '[x]) instance Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : xs)) (Data.Diverse.Which.Internal.Switcher Data.Diverse.Which.Internal.CaseEqWhich GHC.Types.Bool (x : xs)) => GHC.Classes.Eq (Data.Diverse.Which.Internal.Which (x : xs)) instance GHC.Classes.Eq (Data.Diverse.Which.Internal.Which '[]) instance Data.Diverse.Reiterate.Reiterate (Data.Diverse.Which.Internal.CaseEqWhich r) (x : xs) instance GHC.Classes.Eq x => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseEqWhich GHC.Types.Bool) (x : xs) instance (Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : xs)) (Data.Diverse.Which.Internal.Switcher Data.Diverse.Which.Internal.CaseEqWhich GHC.Types.Bool (x : xs)), Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : xs)) (Data.Diverse.Which.Internal.Switcher Data.Diverse.Which.Internal.CaseOrdWhich GHC.Types.Ordering (x : xs))) => GHC.Classes.Ord (Data.Diverse.Which.Internal.Which (x : xs)) instance GHC.Classes.Ord (Data.Diverse.Which.Internal.Which '[]) instance Data.Diverse.Reiterate.Reiterate (Data.Diverse.Which.Internal.CaseOrdWhich r) (x : xs) instance GHC.Classes.Ord x => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseOrdWhich GHC.Types.Ordering) (x : xs) instance Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : xs)) (Data.Diverse.Which.Internal.Switcher Data.Diverse.Which.Internal.CaseShowWhich GHC.Show.ShowS (x : xs)) => GHC.Show.Show (Data.Diverse.Which.Internal.Which (x : xs)) instance GHC.Show.Show (Data.Diverse.Which.Internal.Which '[]) instance Data.Diverse.Reiterate.Reiterate (Data.Diverse.Which.Internal.CaseShowWhich r) (x : xs) instance GHC.Show.Show x => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseShowWhich GHC.Show.ShowS) (x : xs) instance GHC.Read.Read x => Data.Diverse.Which.Internal.WhichRead (Data.Diverse.Which.Internal.Which_ '[x]) 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)) instance Data.Diverse.Which.Internal.WhichRead (Data.Diverse.Which.Internal.Which_ (x : xs)) => GHC.Read.Read (Data.Diverse.Which.Internal.Which (x : xs)) instance GHC.Read.Read (Data.Diverse.Which.Internal.Which '[]) -- | Re-export Which without the constructor module Data.Diverse.Which -- | A Which is an anonymous sum type (also known as a polymorphic -- variant, or co-record) which can only contain one of the types in the -- typelist. This is essentially a typed version of Dynamic. -- -- The following functions are available can be used to manipulate unique -- types in the typelist -- --
-- pick 'A' @_ @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String] --pick :: forall x xs. UniqueMember x xs => x -> Which xs -- | A variation of pick into a Which where x is the -- first type. -- --
-- pick0 'A' :: Which '[Char, Int, Bool] --pick0 :: x -> Which (x : xs) -- | A variation of pick into a Which of a single type. -- --
-- pickOnly 'A' :: Which '[Char] --pickOnly :: x -> Which '[x] -- | 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 proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> x -> Which xs -- | Lift a value into a Which of possibly other (possibley -- indistinct) types, where the value is the n-th type. -- --
-- pickN (Proxy @4) (5 :: Int) :: Which '[Bool, Int, Char, Bool, Int, Char] --pickN :: forall n xs proxy x. MemberAt n x xs => proxy n -> x -> Which xs -- | It is obvious what value is inside a Which of one type. -- --
-- let x = pick' 'A' :: Which '[Char] -- obvious x `shouldBe` 'A' --obvious :: Which '[a] -> a -- | trial a type in a Which and Either get the -- Right value or the Left-over possibilities. -- --
-- let x = pick 'A' @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String] -- trial @Char x `shouldBe` Right 'A' -- trial @Int x `shouldBe` Left (pick 'A') :: Which '[Bool, Char, Maybe String] --trial :: forall x xs. (UniqueMember x xs) => Which xs -> Either (Which (Remove x xs)) x -- | Variation of trial which returns a Maybe trial' :: forall x xs. (UniqueMember x xs) => Which xs -> Maybe x -- | A variation of a Which trial which trials the -- first type in the type list. -- --
-- let x = pick 'A' @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String] -- trial0 x `shouldBe` Left (pick 'A') :: Which '[Bool, Char, Maybe String] --trial0 :: forall x xs. Which (x : xs) -> Either (Which xs) x -- | Variation of trial0 which returns a Maybe trial0' :: forall x xs. Which (x : xs) -> Maybe x -- | 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 proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Which xs -> Either (Which (Remove x xs)) x -- | Variation of trialL which returns a Maybe trialL' :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Which xs -> Maybe x -- | trialN the n-th type of a Which, and get Either -- the Right value or the Left-over possibilities. -- --
-- let x = pick 'A' @_ @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String] -- trialN @_ @1 Proxy x `shouldBe` Left (pick 'A') :: Which '[Int, Char, Maybe String] --trialN :: forall n xs proxy x. (MemberAt n x xs) => proxy n -> Which xs -> Either (Which (RemoveIndex n xs)) x -- | Variation of trialN which returns a Maybe trialN' :: forall n xs proxy x. (MemberAt n x xs) => proxy n -> Which xs -> Maybe x -- | A friendlier constraint synonym for diversify. type Diversify (branch :: [Type]) (tree :: [Type]) = Reduce (Which branch) (Switcher (CaseDiversify branch tree) (Which tree) branch) -- | Convert a Which to another Which that may include other -- possibilities. That is, branch is equal or is a subset of -- tree. -- -- This can also be used to rearrange the order of the types in the -- Which. -- -- It is a compile error if tree has duplicate types with -- branch. -- -- NB. Use TypeApplications with _ to specify tree@. -- --
-- let a = pick' (5 :: Int) :: Which '[Int] -- b = diversify @_ @[Int, Bool] a :: Which '[Int, Bool] -- c = diversify @_ @[Bool, Int] b :: Which '[Bool, Int] --diversify :: forall branch tree. Diversify branch tree => Which branch -> Which tree -- | A restricted version of diversify which only rearranges the -- types diversify' :: forall branch tree. (Diversify branch tree, SameLength branch tree) => Which branch -> Which tree -- | A simple version of diversify which add another type to the -- front of the typelist. diversify0 :: forall x xs. Which xs -> Which (x : xs) -- | A variation of diversify where branchis 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'' (CaseFunc @Typeable (show . typeRep . (pure @Proxy))) `shouldBe` "Tagged * Bar Int" --diversifyL :: forall ls branch tree proxy. (Diversify branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) => proxy ls -> Which branch -> Which tree -- | A friendlier constraint synonym for diversifyN. type DiversifyN (indices :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (Reduce (Which branch) (SwitcherN (CaseDiversifyN indices) (Which tree) 0 branch), KindsAtIndices indices tree ~ branch) -- | A variation of diversify which uses a Nat list indices -- to specify how to reorder the fields, where -- --
-- indices[branch_idx] = tree_idx ---- -- This variation allows tree to contain duplicate types with -- branch since the mapping is specified by indicies. -- --
-- let y = pickOnly (5 :: Int) -- y' = diversifyN @'[0] @_ @[Int, Bool] Proxy y -- y'' = diversifyN @[1,0] @_ @[Bool, Int] Proxy y' -- switch y'' (CaseFunc @Typeable (show . typeRep . (pure @Proxy))) `shouldBe` "Int" --diversifyN :: forall indices branch tree proxy. (DiversifyN indices branch tree) => proxy indices -> Which branch -> Which tree -- | A friendlier constraint synonym for reinterpret. type Reinterpret branch tree = Reduce (Which tree) (Switcher (CaseReinterpret branch tree) (Either (Which (Complement tree branch)) (Which branch)) tree) -- | Convert a Which into possibly another Which with a -- totally different typelist. Returns either a Which with the -- Right value, or a Which with the Leftover -- compliment types. -- -- It is a compile error if branch or compliment has -- duplicate types with tree. -- -- NB. forall used to specify branch first, so TypeApplications -- can be used to specify branch first. -- --
-- let a = pick @[Int, Char, Bool] (5 :: Int) :: Which '[Int, Char, Bool] -- let b = reinterpret [String, Char] y -- b `shouldBe` Left (pick (5 :: Int)) :: Which '[Int, Bool] -- let c = reinterpret [String, Int] a -- c `shouldBe` Right (pick (5 :: Int)) :: Which '[String, Int] --reinterpret :: forall branch tree. Reinterpret branch tree => Which tree -> Either (Which (Complement tree branch)) (Which branch) -- | A friendlier constraint synonym for reinterpret'. type Reinterpret' branch tree = Reduce (Which tree) (Switcher (CaseReinterpret' branch tree) (Maybe (Which branch)) tree) -- | Variation of reinterpret which returns a Maybe. reinterpret' :: forall branch tree. Reinterpret' branch tree => Which tree -> Maybe (Which branch) -- | 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) -- | Variation of reinterpretL which returns a Maybe. reinterpretL' :: forall ls branch tree proxy. (Reinterpret' branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) => proxy ls -> Which tree -> Maybe (Which branch) -- | A friendlier constraint synonym for reinterpretN. type ReinterpretN' (indices :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (Reduce (Which tree) (SwitcherN (CaseReinterpretN' indices) (Maybe (Which branch)) 0 tree), KindsAtIndices indices tree ~ branch) -- | A limited variation of reinterpret which uses a Nat list -- n to specify how to reorder the fields, where -- --
-- indices[branch_idx] = tree_idx ---- -- This variation allows tree to contain duplicate types with -- branch since the mapping is specified by indicies. -- -- However, unlike reinterpert, in this variation, -- branch must be a subset of tree instead of any -- arbitrary Which. Also it returns a Maybe instead of Either. -- -- This is so that the same indices can be used in -- narrowN. reinterpretN' :: forall (indices :: [Nat]) branch tree proxy. (ReinterpretN' indices branch tree) => proxy indices -> Which tree -> Maybe (Which branch) -- | A friendlier constraint synonym for switch. type Switch c r xs = Reduce (Which xs) (Switcher c r xs) -- | Switcher is an instance of Reduce for which -- reiterates through the possibilities in a Which, -- delegating handling to Case, ensuring termination when -- Which only contains one type. newtype Switcher c r (xs :: [Type]) Switcher :: (c r xs) -> Switcher c r -- | Catamorphism for Which. This is equivalent to flip -- switch. which :: Switch c r xs => c r xs -> Which xs -> r -- | A switch/case statement for Which. This is equivalent to -- flip which -- -- Use Case instances like Cases to apply a Which of -- functions to a variant of values. -- --
-- let y = pick (5 :: Int) :: Which '[Int, Bool] -- switch y ( -- cases (show @Bool -- ./ show @Int -- ./ nil)) `shouldBe` "5" ---- -- Or CaseFunc @Typeable to apply a polymorphic function -- that work on all Typeables. -- --
-- let y = pick (5 :: Int) :: Which '[Int, Bool] -- switch y (CaseFunc @Typeable (show . typeRep . (pure @Proxy))) `shouldBe` Int ---- -- Or you may use your own custom instance of Case. switch :: Switch c r xs => Which xs -> c r xs -> r -- | A friendlier constraint synonym for switch. type SwitchN c r n xs = Reduce (Which xs) (SwitcherN c r n xs) -- | SwitcherN is a variation of Switcher which -- reiterateNs through the possibilities in a Which, -- delegating work to CaseN, ensuring termination when -- Which only contains one type. newtype SwitcherN c r (n :: Nat) (xs :: [Type]) SwitcherN :: (c r n xs) -> SwitcherN c r -- | Catamorphism for Which. This is equivalent to flip -- switchN. whichN :: SwitchN c r n xs => c r n xs -> Which xs -> r -- | A switch/case statement for Which. This is equivalent to -- flip whichN -- -- Use Case instances like CasesN to apply a Which -- of functions to a variant of values in index order. -- --
-- let y = pickN @0 Proxy (5 :: Int) :: Which '[Int, Bool, Bool, Int] -- switchN y ( -- casesN (show @Int -- ./ show @Bool -- ./ show @Bool -- ./ show @Int -- ./ nil)) `shouldBe` "5" ---- -- Or you may use your own custom instance of Case. switchN :: SwitchN c r n xs => Which xs -> c r n xs -> r module Data.Diverse.AFunctor -- | Given a Case that transforms each type in the typelist, convert -- a f xs to f (CasesResult2 c xs) class AFunctor f c xs afmap :: AFunctor f c xs => c xs -> f xs -> f (CaseResults c xs) module Data.Diverse.AFoldable -- | Constrained Foldable for a specified type instead for all types. class AFoldable t a afoldr :: AFoldable t a => (a -> b -> b) -> b -> t a -> b afoldl' :: AFoldable t a => (b -> a -> b) -> b -> t a -> b module Data.Diverse.Many.Internal -- | 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 -- --
-- Key = Index of type in typelist + Offset ---- -- The constructor will guarantee the correct number and types of the -- elements. The constructor is only exported in the -- Data.Diverse.Many.Internal module newtype Many (xs :: [Type]) Many :: (Seq Any) -> Many -- | This instance allows converting to and from Many There are instances -- for converting tuples of up to size 15. class IsMany t xs a toMany :: IsMany t xs a => t xs a -> Many xs fromMany :: IsMany t xs a => Many xs -> t xs a -- | Converts from a Many to a value (eg a tuple), via a Tagged wrapper fromMany' :: IsMany Tagged xs a => Many xs -> a -- | Converts from a value (eg a tuple) to a Many, via a -- Tagged wrapper toMany' :: IsMany Tagged xs a => a -> Many xs -- | Analogous to null. Named nil to avoid conflicting with -- null. nil :: Many '[] -- | Create a Many from a single value. Analogous to singleton single :: x -> Many '[x] -- | Add an element to the left of a Many. Not named cons to avoid -- conflict with cons prefix :: x -> Many xs -> Many (x : xs) infixr 5 `prefix` -- | Infix version of prefix. -- -- Mnemonic: Element on the left is smaller ./ than the larger -- Many to the right. (./) :: x -> Many xs -> Many (x : xs) infixr 5 ./ -- | Add an element to the right of a Many Not named snoc to avoid -- conflict with snoc postfix :: Many xs -> y -> Many (Append xs '[y]) infixl 5 `postfix` -- | Add an element to the right of a Many iff the field doesn't already -- exist. postfix' :: forall y xs. MaybeUniqueMember y xs => Many xs -> y -> Many (SnocUnique xs y) infixl 5 `postfix'` -- | Infix version of postfix. -- -- Mnemonic: Many is larger \. than the smaller element (\.) :: Many xs -> y -> Many (Append xs '[y]) infixl 5 \. -- | Appends two Manys together append :: Many xs -> Many ys -> Many (Append xs ys) infixr 5 `append` class CanAppendUnique xs ys -- | Appends the unique fields fields from the right Many using -- postfix' append' :: CanAppendUnique xs ys => Many xs -> Many ys -> Many (AppendUnique xs ys) -- | Infix version of append. -- -- Mnemonic: prefix ./ with an extra slash (meaning -- Many) in front. (/./) :: Many xs -> Many ys -> Many (Append xs ys) infixr 5 /./ -- | Split a non-empty Many into the first element, then the rest of the -- Many. Analogous to viewl viewf :: Many (x : xs) -> (x, Many xs) -- | Split a non-empty Many into initial part of Many, and the last -- element. Analogous to viewr viewb :: Many (x : xs) -> (Many (Init (x : xs)), Last (x : xs)) -- | Extract the first element of a Many, which guaranteed to be non-empty. -- Analogous to head front :: Many (x : xs) -> x -- | Extract the back element of a Many, which guaranteed to be -- non-empty. Analogous to last back :: Many (x : xs) -> Last (x : xs) -- | Extract the elements after the front of a Many, which guaranteed to be -- non-empty. Analogous to tail aft :: Many (x : xs) -> Many xs -- | Return all the elements of a Many except the back one, which -- guaranteed to be non-empty. Analogous to init fore :: Many (x : xs) -> Many (Init (x : xs)) -- | Getter by unique type. Get the field with type x. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil -- fetch @Int x `shouldBe` 5 --fetch :: forall x xs. UniqueMember x xs => Many xs -> x -- | 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 proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> x -- | Getter by index. Get the value of the field at index type-level Nat -- n -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil -- fetchN @1 Proxy x `shouldBe` False --fetchN :: forall n xs proxy x. MemberAt n x xs => proxy n -> Many xs -> x -- | Setter by unique type. Set the field with type x. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil -- replace @Int x 6 `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil --replace :: forall x xs. UniqueMember x xs => Many xs -> x -> Many xs -- | Polymorphic setter by unique type. Set the field with type x, -- and replace with type y -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil -- replace' @Int Proxy x (Just True) `shouldBe` Just True ./ False ./ 'X' ./ Just 'O' ./ nil --replace' :: forall x y xs proxy. UniqueMember x xs => proxy x -> Many xs -> y -> Many (Replace x y xs) -- | 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 proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> x -> Many xs -- | 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 proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> y -> Many (Replace x y xs) -- | Setter by index. Set the value of the field at index type-level Nat -- n -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil -- replaceN @0 Proxy x 7 shouldBe --replaceN :: forall n xs proxy x. MemberAt n x xs => proxy n -> Many xs -> x -> Many xs -- | Polymorphic version of replaceN replaceN' :: forall n y xs proxy x. MemberAt n x xs => proxy n -> Many xs -> y -> Many (ReplaceIndex n y xs) -- | A friendlier type constraint synomyn for select type Select (smaller :: [Type]) (larger :: [Type]) = AFoldable (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. -- -- This can also be used to reorder fields in the original Many. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- select @'[Bool, Char] x `shouldBe` False ./ 'X' ./ nil --select :: forall smaller larger. Select smaller larger => Many larger -> Many smaller -- | 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 -- | A friendlier type constraint synomyn for selectN type SelectN (ns :: [Nat]) (smaller :: [Type]) (larger :: [Type]) = (AFoldable (CollectorAnyN (CaseSelectN ns smaller) 0 larger) (Maybe (Int, WrappedAny)), smaller ~ KindsAtIndices ns larger, IsDistinct ns) -- | A variation of select which uses a Nat list n to -- specify how to reorder the fields, where -- --
-- indices[branch_idx] = tree_idx@ ---- -- This variation allows smaller or larger to contain -- indistinct since the mapping is specified by indicies. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- selectN (Proxy @'[5, 4, 0]) x `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nil --selectN :: forall ns smaller larger proxy. SelectN ns smaller larger => proxy ns -> Many larger -> Many smaller -- | A friendlier type constraint synomyn for amend 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' ./ 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 -- | A friendlier type constraint synomyn for amend' type Amend' smaller smaller' larger = (AFoldable (CollectorAny (CaseAmend' larger) (Zip smaller smaller')) (Int, WrappedAny), IsDistinct smaller) amend' :: forall smaller smaller' larger proxy. Amend' smaller smaller' larger => proxy smaller -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger) -- | 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 -- | 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 ./ 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
--
amendL' :: forall ls smaller smaller' larger proxy. (Amend' smaller smaller' larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger)
-- | A friendlier type constraint synomyn for amendN
type AmendN ns smaller larger = (AFoldable (CollectorAnyN (CaseAmendN ns larger) 0 smaller) (Int, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns)
-- | A variation of amend which uses a Nat list n to
-- specify how to reorder the fields, where
--
-- -- indices[branch_idx] = tree_idx@ ---- -- This variation allows smaller or larger to contain -- indistinct since the mapping is specified by indicies. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- amendN (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 -- | A friendlier type constraint synomyn for amendN type AmendN' ns smaller smaller' larger = (AFoldable (CollectorAnyN (CaseAmendN' ns larger) 0 (Zip smaller smaller')) (Int, 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) -- | A friendlier type constraint synomyn for collect and -- forMany type Collect c r (xs :: [Type]) = (AFoldable (Collector c xs) r, Case (c r) 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. -- -- 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 -- | Folds any Many, even with indistinct types. Given -- distinct handlers for the fields in Many, create -- AFoldable of the results of running the handlers over the -- fields in Many. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- y = show @Int ./ show @Char ./ show @(Maybe Char) ./ show @Bool ./ nil -- afoldr (:) [] (forMany (cases y) x) `shouldBe` -- ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"] --forMany :: Collect c r xs => c r xs -> Many xs -> Collector c xs r -- | This is flip forMany -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- y = show @Int ./ show @Char ./ show @(Maybe Char) ./ show @Bool ./ nil -- afoldr (:) [] (collect x (cases y)) `shouldBe` -- ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"] --collect :: (Collect c r xs) => Many xs -> c r xs -> Collector c xs r -- | A friendlier type constraint synomyn for collect and -- forMany type CollectN c r (n :: Nat) (xs :: [Type]) = (AFoldable (CollectorN c n xs) r, Case (c r n) xs) -- | A variation of Collector which uses ReiterateN instead -- of Reiterate data CollectorN c (n :: Nat) (xs :: [Type]) r -- | Folds any Many, even with indistinct types. Given index -- handlers for the fields in Many, create AFoldable of the -- results of running the handlers over the fields in Many. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- y = show @Int ./ show @Bool ./ show @Char ./ show @(Maybe Char) ./ show @Int ./ show @(Maybe Char) ./ nil -- afoldr (:) [] (forManyN (casesN y) x) `shouldBe` -- ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"] --forManyN :: CollectN c r n xs => c r n xs -> Many xs -> CollectorN c n xs r -- | This is flip forManyN -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- y = show @Int ./ show @Bool ./ show @Char ./ show @(Maybe Char) ./ show @Int ./ show @(Maybe Char) ./ nil -- afoldr (:) [] (collectN x (casesN y)) `shouldBe` -- ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"] --collectN :: CollectN c r n xs => Many xs -> c r n xs -> CollectorN c n xs r -- | Split a Many into two, where the first type in the second Many is -- unique x splitBefore :: forall x xs proxy. (UniqueMember x xs) => proxy x -> Many xs -> (Many (Before x xs), Many (From x xs)) -- | Split a Many into two, where the first type in the second Many is -- unique label l splitBeforeL :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> (Many (Before x xs), Many (From x xs)) -- | Split a Many into two, where the second Many starts at index -- n splitBeforeN :: forall n xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> Many xs -> (Many (BeforeIndex n xs), Many (FromIndex n xs)) -- | Split a Many into two, where the last type in the first Many is unique -- x splitAfter :: forall x xs proxy. (UniqueMember x xs) => proxy x -> Many xs -> (Many (To x xs), Many (After x xs)) -- | Split a Many into two, where the last type in the first Many is unique -- label l splitAfterL :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> (Many (To x xs), Many (After x xs)) -- | Split a Many into two, where the second Many starts at index (n + -- 1) splitAfterN :: forall n xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> Many xs -> (Many (ToIndex n xs), Many (AfterIndex n xs)) -- | Insert a Many into another Many, inserting before a unique x insetBefore :: forall x ys xs proxy. (UniqueMember x xs) => proxy x -> Many ys -> Many xs -> Many (Append (Before x xs) (Append ys (From x xs))) -- | Insert a Many into another Many, inserting before a unique label -- l insetBeforeL :: forall l ys xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many ys -> Many xs -> Many (Append (Before x xs) (Append ys (From x xs))) -- | Insert a Many into another Many, starting at index n insetBeforeN :: forall n ys xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> Many ys -> Many xs -> Many (Append (BeforeIndex n xs) (Append ys (FromIndex n xs))) -- | Insert a Many into another Many, inserting after a unique x insetAfter :: forall x ys xs proxy. (UniqueMember x xs) => proxy x -> Many ys -> Many xs -> Many (Append (To x xs) (Append ys (After x xs))) -- | Insert a Many into another Many, inserting after a unique label -- l insetAfterL :: forall l ys xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many ys -> Many xs -> Many (Append (To x xs) (Append ys (After x xs))) -- | Insert a Many into another Many, starting at index (n + 1) insetAfterN :: forall n ys xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> Many ys -> Many xs -> Many (Append (ToIndex n xs) (Append ys (AfterIndex n xs))) -- | Insert an item into a Many, inserting before unique type x insertBefore :: forall x y xs proxy. (UniqueMember x xs) => proxy x -> y -> Many xs -> Many (Append (Before x xs) (y : From x xs)) -- | Insert an item into a Many, inserting before unique label l insertBeforeL :: forall l y xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> y -> Many xs -> Many (Append (Before x xs) (y : From x xs)) -- | Insert an item into a Many, inserting before index n insertBeforeN :: forall n y xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> y -> Many xs -> Many (Append (BeforeIndex n xs) (y : FromIndex n xs)) -- | Insert an item into a Many, inserting after unique type x insertAfter :: forall x y xs proxy. (UniqueMember x xs) => proxy x -> y -> Many xs -> Many (Append (To x xs) (y : After x xs)) -- | Insert an item into a Many, inserting after unique label l insertAfterL :: forall l y xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> y -> Many xs -> Many (Append (To x xs) (y : After x xs)) -- | Insert an item into a Many, inserting after index n insertAfterN :: forall n y xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> y -> Many xs -> Many (Append (ToIndex n xs) (y : AfterIndex n xs)) -- | Remove the unique x from a Many. Not named delete to -- avoid conflicts with delete remove :: forall x xs proxy. (UniqueMember x xs) => proxy x -> Many xs -> Many (Remove x xs) -- | Remove the unique label l from a Many. removeL :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> Many (Remove x xs) -- | Remove the n-th item from a Many. removeN :: forall n xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> Many xs -> Many (RemoveIndex n xs) instance Control.DeepSeq.NFData (Data.Diverse.Many.Internal.Many '[]) instance (Control.DeepSeq.NFData x, Control.DeepSeq.NFData (Data.Diverse.Many.Internal.Many xs)) => Control.DeepSeq.NFData (Data.Diverse.Many.Internal.Many (x : xs)) instance GHC.Generics.Generic (Data.Diverse.Many.Internal.Many '[]) instance GHC.Generics.Generic (Data.Diverse.Many.Internal.Many (x : xs)) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[] () instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[a] a instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[a, b] (a, b) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[a, b, c] (a, b, c) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[a, b, c, d] (a, b, c, d) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[a, b, c, d, e] (a, b, c, d, e) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[a, b, c, d, e, f] (a, b, c, d, e, f) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[a, b, c, d, e, f, g] (a, b, c, d, e, f, g) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[a, b, c, d, e, f, g, h] (a, b, c, d, e, f, g, h) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[a, b, c, d, e, f, g, h, i] (a, b, c, d, e, f, g, h, i) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[a, b, c, d, e, f, g, h, i, j] (a, b, c, d, e, f, g, h, i, j) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.Tagged '[a, b, c, d, e, f, g, h, i, j, k] (a, b, c, d, e, f, g, h, i, j, k) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.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) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.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) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.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) instance Data.Diverse.Many.Internal.IsMany Data.Tagged.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) instance Data.Diverse.Many.Internal.CanAppendUnique xs '[] instance (Data.Diverse.TypeLevel.MaybeUniqueMember y xs, Data.Diverse.Many.Internal.CanAppendUnique (Data.Diverse.TypeLevel.SnocUnique xs y) ys, Data.Diverse.TypeLevel.AppendUnique (Data.Diverse.TypeLevel.SnocUnique xs y) ys ~ Data.Diverse.TypeLevel.AppendUnique xs (y : ys)) => Data.Diverse.Many.Internal.CanAppendUnique xs (y : ys) instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAny c '[]) r instance (Data.Diverse.Many.Internal.CaseAny (c r) (x : xs), Data.Diverse.Reiterate.Reiterate (c r) (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAny c xs) r, r ~ Data.Diverse.TypeLevel.CaseResult (c r) GHC.Prim.Any) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAny c (x : xs)) r instance forall k (c :: * -> k -> [GHC.Types.Type] -> *) (n :: k) r. Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAnyN c n '[]) r instance (Data.Diverse.Many.Internal.CaseAny (c r n) (x : xs), Data.Diverse.Reiterate.ReiterateN (c r) n (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAnyN c (n GHC.TypeLits.+ 1) xs) r, r ~ Data.Diverse.TypeLevel.CaseResult (c r n) GHC.Prim.Any) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorAnyN c n (x : xs)) r instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.Collector c '[]) r instance (Data.Diverse.Case.Case (c r) (x : xs), Data.Diverse.Reiterate.Reiterate (c r) (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.Collector c xs) r, r ~ Data.Diverse.TypeLevel.CaseResult (c r) x) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.Collector c (x : xs)) r instance Data.Diverse.AFunctor.AFunctor Data.Diverse.Many.Internal.Many_ c '[] instance (Data.Diverse.Reiterate.Reiterate c (a : as), Data.Diverse.AFunctor.AFunctor Data.Diverse.Many.Internal.Many_ c as, Data.Diverse.Case.Case c (a : as)) => Data.Diverse.AFunctor.AFunctor Data.Diverse.Many.Internal.Many_ c (a : as) instance Data.Diverse.AFunctor.AFunctor Data.Diverse.Many.Internal.Many_ c as => Data.Diverse.AFunctor.AFunctor Data.Diverse.Many.Internal.Many c as instance Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorN c n '[]) r instance (Data.Diverse.Case.Case (c r n) (x : xs), Data.Diverse.Reiterate.ReiterateN (c r) n (x : xs), Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorN c (n GHC.TypeLits.+ 1) xs) r, r ~ Data.Diverse.TypeLevel.CaseResult (c r n) x) => Data.Diverse.AFoldable.AFoldable (Data.Diverse.Many.Internal.CollectorN c n (x : xs)) r instance forall k (smaller :: [GHC.Types.Type]) (larger :: [GHC.Types.Type]) (r :: k) x (xs :: [GHC.Types.Type]). Data.Diverse.Reiterate.Reiterate (Data.Diverse.Many.Internal.CaseSelect smaller larger r) (x : xs) instance (Data.Diverse.TypeLevel.UniqueIfExists smaller x larger, Data.Diverse.TypeLevel.MaybeUniqueMember x smaller) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseSelect smaller larger (GHC.Base.Maybe (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny))) (x : xs) instance forall k (indices :: [GHC.Types.Nat]) (smaller :: [GHC.Types.Type]) (r :: k) (n :: GHC.Types.Nat) x (xs :: [GHC.Types.Type]). Data.Diverse.Reiterate.ReiterateN (Data.Diverse.Many.Internal.CaseSelectN indices smaller r) n (x : xs) instance (Data.Diverse.TypeLevel.MaybeMemberAt n' x smaller, n' ~ Data.Diverse.TypeLevel.PositionOf n indices) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseSelectN indices smaller (GHC.Base.Maybe (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)) n) (x : xs) instance forall k (larger :: [GHC.Types.Type]) (r :: k) x (xs :: [GHC.Types.Type]). Data.Diverse.Reiterate.Reiterate (Data.Diverse.Many.Internal.CaseAmend larger r) (x : xs) instance Data.Diverse.TypeLevel.UniqueMember x larger => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmend larger (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)) (x : xs) instance forall k (larger :: [GHC.Types.Type]) (r :: k) z (zs :: [GHC.Types.Type]). Data.Diverse.Reiterate.Reiterate (Data.Diverse.Many.Internal.CaseAmend' larger r) (z : zs) instance Data.Diverse.TypeLevel.UniqueMember x larger => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmend' larger (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)) ((x, y) : zs) instance forall k (indices :: [GHC.Types.Nat]) (larger :: [GHC.Types.Type]) (r :: k) (n :: GHC.Types.Nat) x (xs :: [GHC.Types.Type]). Data.Diverse.Reiterate.ReiterateN (Data.Diverse.Many.Internal.CaseAmendN indices larger r) n (x : xs) instance (Data.Diverse.TypeLevel.MemberAt n' x larger, n' ~ Data.Diverse.TypeLevel.KindAtIndex n indices) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmendN indices larger (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny) n) (x : xs) instance forall k (indices :: [GHC.Types.Nat]) (larger :: [GHC.Types.Type]) (r :: k) (n :: GHC.Types.Nat) z (zs :: [GHC.Types.Type]). Data.Diverse.Reiterate.ReiterateN (Data.Diverse.Many.Internal.CaseAmendN' indices larger r) n (z : zs) instance (Data.Diverse.TypeLevel.MemberAt n' x larger, n' ~ Data.Diverse.TypeLevel.KindAtIndex n indices) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmendN' indices larger (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny) n) ((x, y) : zs) instance GHC.Classes.Eq (Data.Diverse.Many.Internal.Many_ '[]) instance (GHC.Classes.Eq x, GHC.Classes.Eq (Data.Diverse.Many.Internal.Many_ xs)) => GHC.Classes.Eq (Data.Diverse.Many.Internal.Many_ (x : xs)) instance GHC.Classes.Eq (Data.Diverse.Many.Internal.Many_ xs) => GHC.Classes.Eq (Data.Diverse.Many.Internal.Many xs) instance GHC.Classes.Ord (Data.Diverse.Many.Internal.Many_ '[]) instance (GHC.Classes.Ord x, GHC.Classes.Ord (Data.Diverse.Many.Internal.Many_ xs)) => GHC.Classes.Ord (Data.Diverse.Many.Internal.Many_ (x : xs)) instance GHC.Classes.Ord (Data.Diverse.Many.Internal.Many_ xs) => GHC.Classes.Ord (Data.Diverse.Many.Internal.Many xs) instance Data.Semigroup.Semigroup (Data.Diverse.Many.Internal.Many_ '[]) instance (Data.Semigroup.Semigroup x, Data.Semigroup.Semigroup (Data.Diverse.Many.Internal.Many_ xs)) => Data.Semigroup.Semigroup (Data.Diverse.Many.Internal.Many_ (x : xs)) instance Data.Semigroup.Semigroup (Data.Diverse.Many.Internal.Many_ xs) => Data.Semigroup.Semigroup (Data.Diverse.Many.Internal.Many xs) instance GHC.Base.Monoid (Data.Diverse.Many.Internal.Many_ '[]) instance (GHC.Base.Monoid x, GHC.Base.Monoid (Data.Diverse.Many.Internal.Many_ xs)) => GHC.Base.Monoid (Data.Diverse.Many.Internal.Many_ (x : xs)) instance GHC.Base.Monoid (Data.Diverse.Many.Internal.Many_ xs) => GHC.Base.Monoid (Data.Diverse.Many.Internal.Many xs) instance GHC.Show.Show (Data.Diverse.Many.Internal.Many_ '[]) instance (GHC.Show.Show x, GHC.Show.Show (Data.Diverse.Many.Internal.Many_ xs)) => GHC.Show.Show (Data.Diverse.Many.Internal.Many_ (x : xs)) instance GHC.Show.Show (Data.Diverse.Many.Internal.Many_ xs) => GHC.Show.Show (Data.Diverse.Many.Internal.Many xs) instance GHC.Read.Read (Data.Diverse.Many.Internal.Many_ '[]) instance (GHC.Read.Read x, GHC.Read.Read (Data.Diverse.Many.Internal.Many_ xs)) => GHC.Read.Read (Data.Diverse.Many.Internal.Many_ (x : xs)) instance GHC.Read.Read (Data.Diverse.Many.Internal.Many_ xs) => GHC.Read.Read (Data.Diverse.Many.Internal.Many xs) -- | Re-export Many without the constructor module Data.Diverse.Many -- | 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 -- --
-- Key = Index of type in typelist + Offset ---- -- The constructor will guarantee the correct number and types of the -- elements. The constructor is only exported in the -- Data.Diverse.Many.Internal module data Many (xs :: [Type]) -- | This instance allows converting to and from Many There are instances -- for converting tuples of up to size 15. class IsMany t xs a toMany :: IsMany t xs a => t xs a -> Many xs fromMany :: IsMany t xs a => Many xs -> t xs a -- | Converts from a Many to a value (eg a tuple), via a Tagged wrapper fromMany' :: IsMany Tagged xs a => Many xs -> a -- | Converts from a value (eg a tuple) to a Many, via a -- Tagged wrapper toMany' :: IsMany Tagged xs a => a -> Many xs -- | Analogous to null. Named nil to avoid conflicting with -- null. nil :: Many '[] -- | Create a Many from a single value. Analogous to singleton single :: x -> Many '[x] -- | Add an element to the left of a Many. Not named cons to avoid -- conflict with cons prefix :: x -> Many xs -> Many (x : xs) infixr 5 `prefix` -- | Infix version of prefix. -- -- Mnemonic: Element on the left is smaller ./ than the larger -- Many to the right. (./) :: x -> Many xs -> Many (x : xs) infixr 5 ./ -- | Add an element to the right of a Many Not named snoc to avoid -- conflict with snoc postfix :: Many xs -> y -> Many (Append xs '[y]) infixl 5 `postfix` -- | Add an element to the right of a Many iff the field doesn't already -- exist. postfix' :: forall y xs. MaybeUniqueMember y xs => Many xs -> y -> Many (SnocUnique xs y) infixl 5 `postfix'` -- | Infix version of postfix. -- -- Mnemonic: Many is larger \. than the smaller element (\.) :: Many xs -> y -> Many (Append xs '[y]) infixl 5 \. -- | Appends two Manys together append :: Many xs -> Many ys -> Many (Append xs ys) infixr 5 `append` class CanAppendUnique xs ys -- | Appends the unique fields fields from the right Many using -- postfix' append' :: CanAppendUnique xs ys => Many xs -> Many ys -> Many (AppendUnique xs ys) -- | Infix version of append. -- -- Mnemonic: prefix ./ with an extra slash (meaning -- Many) in front. (/./) :: Many xs -> Many ys -> Many (Append xs ys) infixr 5 /./ -- | Split a non-empty Many into the first element, then the rest of the -- Many. Analogous to viewl viewf :: Many (x : xs) -> (x, Many xs) -- | Split a non-empty Many into initial part of Many, and the last -- element. Analogous to viewr viewb :: Many (x : xs) -> (Many (Init (x : xs)), Last (x : xs)) -- | Extract the first element of a Many, which guaranteed to be non-empty. -- Analogous to head front :: Many (x : xs) -> x -- | Extract the back element of a Many, which guaranteed to be -- non-empty. Analogous to last back :: Many (x : xs) -> Last (x : xs) -- | Extract the elements after the front of a Many, which guaranteed to be -- non-empty. Analogous to tail aft :: Many (x : xs) -> Many xs -- | Return all the elements of a Many except the back one, which -- guaranteed to be non-empty. Analogous to init fore :: Many (x : xs) -> Many (Init (x : xs)) -- | Getter by unique type. Get the field with type x. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil -- fetch @Int x `shouldBe` 5 --fetch :: forall x xs. UniqueMember x xs => Many xs -> x -- | 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 proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> x -- | Getter by index. Get the value of the field at index type-level Nat -- n -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil -- fetchN @1 Proxy x `shouldBe` False --fetchN :: forall n xs proxy x. MemberAt n x xs => proxy n -> Many xs -> x -- | Setter by unique type. Set the field with type x. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil -- replace @Int x 6 `shouldBe` (6 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil --replace :: forall x xs. UniqueMember x xs => Many xs -> x -> Many xs -- | Polymorphic setter by unique type. Set the field with type x, -- and replace with type y -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil -- replace' @Int Proxy x (Just True) `shouldBe` Just True ./ False ./ 'X' ./ Just 'O' ./ nil --replace' :: forall x y xs proxy. UniqueMember x xs => proxy x -> Many xs -> y -> Many (Replace x y xs) -- | 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 proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> x -> Many xs -- | 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 proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> y -> Many (Replace x y xs) -- | Setter by index. Set the value of the field at index type-level Nat -- n -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ nil -- replaceN @0 Proxy x 7 shouldBe --replaceN :: forall n xs proxy x. MemberAt n x xs => proxy n -> Many xs -> x -> Many xs -- | Polymorphic version of replaceN replaceN' :: forall n y xs proxy x. MemberAt n x xs => proxy n -> Many xs -> y -> Many (ReplaceIndex n y xs) -- | A friendlier type constraint synomyn for select type Select (smaller :: [Type]) (larger :: [Type]) = AFoldable (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. -- -- This can also be used to reorder fields in the original Many. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- select @'[Bool, Char] x `shouldBe` False ./ 'X' ./ nil --select :: forall smaller larger. Select smaller larger => Many larger -> Many smaller -- | 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 -- | A friendlier type constraint synomyn for selectN type SelectN (ns :: [Nat]) (smaller :: [Type]) (larger :: [Type]) = (AFoldable (CollectorAnyN (CaseSelectN ns smaller) 0 larger) (Maybe (Int, WrappedAny)), smaller ~ KindsAtIndices ns larger, IsDistinct ns) -- | A variation of select which uses a Nat list n to -- specify how to reorder the fields, where -- --
-- indices[branch_idx] = tree_idx@ ---- -- This variation allows smaller or larger to contain -- indistinct since the mapping is specified by indicies. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- selectN (Proxy @'[5, 4, 0]) x `shouldBe` Just 'A' ./ (6 :: Int) ./ (5 ::Int) ./ nil --selectN :: forall ns smaller larger proxy. SelectN ns smaller larger => proxy ns -> Many larger -> Many smaller -- | A friendlier type constraint synomyn for amend 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' ./ 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 -- | A friendlier type constraint synomyn for amend' type Amend' smaller smaller' larger = (AFoldable (CollectorAny (CaseAmend' larger) (Zip smaller smaller')) (Int, WrappedAny), IsDistinct smaller) amend' :: forall smaller smaller' larger proxy. Amend' smaller smaller' larger => proxy smaller -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger) -- | 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 -- | 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 ./ 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
--
amendL' :: forall ls smaller smaller' larger proxy. (Amend' smaller smaller' larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger) => proxy ls -> Many larger -> Many smaller' -> Many (Replaces smaller smaller' larger)
-- | A friendlier type constraint synomyn for amendN
type AmendN ns smaller larger = (AFoldable (CollectorAnyN (CaseAmendN ns larger) 0 smaller) (Int, WrappedAny), smaller ~ KindsAtIndices ns larger, IsDistinct ns)
-- | A variation of amend which uses a Nat list n to
-- specify how to reorder the fields, where
--
-- -- indices[branch_idx] = tree_idx@ ---- -- This variation allows smaller or larger to contain -- indistinct since the mapping is specified by indicies. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- amendN (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 -- | A friendlier type constraint synomyn for amendN type AmendN' ns smaller smaller' larger = (AFoldable (CollectorAnyN (CaseAmendN' ns larger) 0 (Zip smaller smaller')) (Int, 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) -- | A friendlier type constraint synomyn for collect and -- forMany type Collect c r (xs :: [Type]) = (AFoldable (Collector c xs) r, Case (c r) 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. -- -- 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 -- | Folds any Many, even with indistinct types. Given -- distinct handlers for the fields in Many, create -- AFoldable of the results of running the handlers over the -- fields in Many. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- y = show @Int ./ show @Char ./ show @(Maybe Char) ./ show @Bool ./ nil -- afoldr (:) [] (forMany (cases y) x) `shouldBe` -- ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"] --forMany :: Collect c r xs => c r xs -> Many xs -> Collector c xs r -- | This is flip forMany -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- y = show @Int ./ show @Char ./ show @(Maybe Char) ./ show @Bool ./ nil -- afoldr (:) [] (collect x (cases y)) `shouldBe` -- ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"] --collect :: (Collect c r xs) => Many xs -> c r xs -> Collector c xs r -- | A friendlier type constraint synomyn for collect and -- forMany type CollectN c r (n :: Nat) (xs :: [Type]) = (AFoldable (CollectorN c n xs) r, Case (c r n) xs) -- | A variation of Collector which uses ReiterateN instead -- of Reiterate data CollectorN c (n :: Nat) (xs :: [Type]) r -- | Folds any Many, even with indistinct types. Given index -- handlers for the fields in Many, create AFoldable of the -- results of running the handlers over the fields in Many. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- y = show @Int ./ show @Bool ./ show @Char ./ show @(Maybe Char) ./ show @Int ./ show @(Maybe Char) ./ nil -- afoldr (:) [] (forManyN (casesN y) x) `shouldBe` -- ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"] --forManyN :: CollectN c r n xs => c r n xs -> Many xs -> CollectorN c n xs r -- | This is flip forManyN -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nil -- y = show @Int ./ show @Bool ./ show @Char ./ show @(Maybe Char) ./ show @Int ./ show @(Maybe Char) ./ nil -- afoldr (:) [] (collectN x (casesN y)) `shouldBe` -- ["5", "False", "'X'", "Just 'O'", "6", "Just 'A'"] --collectN :: CollectN c r n xs => Many xs -> c r n xs -> CollectorN c n xs r -- | Split a Many into two, where the first type in the second Many is -- unique x splitBefore :: forall x xs proxy. (UniqueMember x xs) => proxy x -> Many xs -> (Many (Before x xs), Many (From x xs)) -- | Split a Many into two, where the first type in the second Many is -- unique label l splitBeforeL :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> (Many (Before x xs), Many (From x xs)) -- | Split a Many into two, where the second Many starts at index -- n splitBeforeN :: forall n xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> Many xs -> (Many (BeforeIndex n xs), Many (FromIndex n xs)) -- | Split a Many into two, where the last type in the first Many is unique -- x splitAfter :: forall x xs proxy. (UniqueMember x xs) => proxy x -> Many xs -> (Many (To x xs), Many (After x xs)) -- | Split a Many into two, where the last type in the first Many is unique -- label l splitAfterL :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> (Many (To x xs), Many (After x xs)) -- | Split a Many into two, where the second Many starts at index (n + -- 1) splitAfterN :: forall n xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> Many xs -> (Many (ToIndex n xs), Many (AfterIndex n xs)) -- | Insert a Many into another Many, inserting before a unique x insetBefore :: forall x ys xs proxy. (UniqueMember x xs) => proxy x -> Many ys -> Many xs -> Many (Append (Before x xs) (Append ys (From x xs))) -- | Insert a Many into another Many, inserting before a unique label -- l insetBeforeL :: forall l ys xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many ys -> Many xs -> Many (Append (Before x xs) (Append ys (From x xs))) -- | Insert a Many into another Many, starting at index n insetBeforeN :: forall n ys xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> Many ys -> Many xs -> Many (Append (BeforeIndex n xs) (Append ys (FromIndex n xs))) -- | Insert a Many into another Many, inserting after a unique x insetAfter :: forall x ys xs proxy. (UniqueMember x xs) => proxy x -> Many ys -> Many xs -> Many (Append (To x xs) (Append ys (After x xs))) -- | Insert a Many into another Many, inserting after a unique label -- l insetAfterL :: forall l ys xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many ys -> Many xs -> Many (Append (To x xs) (Append ys (After x xs))) -- | Insert a Many into another Many, starting at index (n + 1) insetAfterN :: forall n ys xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> Many ys -> Many xs -> Many (Append (ToIndex n xs) (Append ys (AfterIndex n xs))) -- | Insert an item into a Many, inserting before unique type x insertBefore :: forall x y xs proxy. (UniqueMember x xs) => proxy x -> y -> Many xs -> Many (Append (Before x xs) (y : From x xs)) -- | Insert an item into a Many, inserting before unique label l insertBeforeL :: forall l y xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> y -> Many xs -> Many (Append (Before x xs) (y : From x xs)) -- | Insert an item into a Many, inserting before index n insertBeforeN :: forall n y xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> y -> Many xs -> Many (Append (BeforeIndex n xs) (y : FromIndex n xs)) -- | Insert an item into a Many, inserting after unique type x insertAfter :: forall x y xs proxy. (UniqueMember x xs) => proxy x -> y -> Many xs -> Many (Append (To x xs) (y : After x xs)) -- | Insert an item into a Many, inserting after unique label l insertAfterL :: forall l y xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> y -> Many xs -> Many (Append (To x xs) (y : After x xs)) -- | Insert an item into a Many, inserting after index n insertAfterN :: forall n y xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> y -> Many xs -> Many (Append (ToIndex n xs) (y : AfterIndex n xs)) -- | Remove the unique x from a Many. Not named delete to -- avoid conflicts with delete remove :: forall x xs proxy. (UniqueMember x xs) => proxy x -> Many xs -> Many (Remove x xs) -- | Remove the unique label l from a Many. removeL :: forall l xs proxy x. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => proxy l -> Many xs -> Many (Remove x xs) -- | Remove the n-th item from a Many. removeN :: forall n xs proxy. (KnownNat n, (n + 1) <= Length xs) => proxy n -> Many xs -> Many (RemoveIndex n xs) module Data.Diverse.Cases -- | Contains a Many of handlers/continuations for all the types in -- the xs typelist. This uses fetch to get the -- unique handler for the type at the Head of xs. -- -- Use cases to construct this with SameLength constraint -- to reduce programming confusion. data Cases (fs :: [Type]) r (xs :: [Type]) -- | Create an instance of Case for either handling switching -- a Which. -- --
-- let y = pick (5 :: Int) :: Which '[Int, Bool] -- switch y ( -- cases (show @Bool -- ./ show @Int -- ./ nul)) `shouldBe` "5" ---- -- Or for handling collect from a Many. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul -- y = show @Int ./ show @Char ./ show @(Maybe Char) ./ show @Bool ./ nul -- afoldr (:) [] (collect x (cases y)) `shouldBe` -- ["5", "False", "X", "Just 'O'", "6", "Just 'A'"] ---- -- 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 :: forall r xs fs. (AllConstrained ((~) r) (CaseResults (Cases fs r) fs), SameLength fs (Nub xs)) => Many fs -> Cases fs r xs -- | A variation of cases without the SameLength constraint -- to allow creating a master-of-all-Case. cases' :: forall r xs fs. (AllConstrained ((~) r) (CaseResults (Cases fs r) fs)) => Many fs -> Cases fs r xs -- | A variation of Cases which uses fetchN to get the -- handler by index. There may be different handlers for the same type, -- but the handlers must be in the same order as the input xs -- typelist. Use casesN to construct this safely ensuring -- n starts at 0. data CasesN (fs :: [Type]) r (n :: Nat) (xs :: [Type]) -- | Safe Constructor for CasesN ensuring that the n Nat -- starts at 0. It is an instance of CaseN for either handling -- switchNing a Which in index order. -- --
-- let y = pickN @0 Proxy (5 :: Int) :: Which '[Int, Bool, Bool, Int] -- switchN y ( -- casesN (show @Int -- ./ show @Bool -- ./ show @Bool -- ./ show @Int -- ./ nul)) `shouldBe` "5" ---- -- Or for handling collectN from a Many. -- --
-- let x = (5 :: Int) ./ False ./ 'X' ./ Just 'O' ./ (6 :: Int) ./ Just 'A' ./ nul -- y = show @Int ./ show @Bool ./ show @Char ./ show @(Maybe Char) ./ show @Int ./ show @(Maybe Char) ./ nul -- afoldr (:) [] (collectN x (casesN y)) `shouldBe` -- ["5", "False", "X", "Just 'O'", "6", "Just 'A'"] --casesN :: forall r xs fs. (AllConstrained ((~) r) (CaseResults (CasesN fs r 0) fs), SameLength fs xs) => Many fs -> CasesN fs r 0 xs -- | A variation of casesN without the SameLength -- constraint to allow creating a master-of-all-Case. casesN' :: forall r xs fs. (AllConstrained ((~) r) (CaseResults (CasesN fs r 0) fs)) => Many fs -> CasesN fs r 0 xs instance Data.Diverse.Reiterate.Reiterate (Data.Diverse.Cases.Cases fs r) xs instance Data.Diverse.TypeLevel.UniqueMember (Data.Diverse.TypeLevel.Head xs -> r) fs => Data.Diverse.Case.Case (Data.Diverse.Cases.Cases fs r) xs instance Data.Diverse.Reiterate.ReiterateN (Data.Diverse.Cases.CasesN fs r) n xs instance Data.Diverse.TypeLevel.MemberAt n (Data.Diverse.TypeLevel.Head xs -> r) fs => Data.Diverse.Case.Case (Data.Diverse.Cases.CasesN fs r n) xs module Data.Diverse