packages feed

data-diverse 0.4.0.0 → 0.5.0.0

raw patch · 15 files changed

+392/−382 lines, 15 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Diverse.CaseTypeable: instance Data.Typeable.Internal.Typeable (Data.Diverse.Type.Head xs) => Data.Diverse.Case.Case Data.Diverse.CaseTypeable.CaseTypeable xs r
- Data.Diverse.Cases: instance Data.Diverse.Type.MemberAt n (Data.Diverse.Type.Head xs -> r) fs => Data.Diverse.Case.Case (Data.Diverse.Cases.CasesN fs n) xs r
- Data.Diverse.Cases: instance Data.Diverse.Type.UniqueMember (Data.Diverse.Type.Head xs -> r) fs => Data.Diverse.Case.Case (Data.Diverse.Cases.Cases fs) xs r
- Data.Diverse.Many.Internal: instance (Data.Diverse.Type.MaybeMemberAt n' x smaller, n' ~ Data.Diverse.Type.PositionOf n indices) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseSelectN indices smaller n) (x : xs) (GHC.Base.Maybe (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny))
- Data.Diverse.Many.Internal: instance (Data.Diverse.Type.MemberAt n' x larger, n' ~ Data.Diverse.Type.KindAtIndex n indices) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmendN indices larger n) (x : xs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
- Data.Diverse.Many.Internal: instance (Data.Diverse.Type.MemberAt n' x larger, n' ~ Data.Diverse.Type.KindAtIndex n indices) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmendN' indices larger n) ((x, y) : zs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
- Data.Diverse.Many.Internal: instance (Data.Diverse.Type.UniqueIfExists smaller x larger, Data.Diverse.Type.MaybeUniqueMemberAt n x smaller) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseSelect smaller larger) (x : xs) (GHC.Base.Maybe (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny))
- Data.Diverse.Many.Internal: instance Data.Diverse.Type.UniqueMemberAt n x larger => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmend larger) (x : xs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
- Data.Diverse.Many.Internal: instance Data.Diverse.Type.UniqueMemberAt n x larger => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmend' larger) ((x, y) : zs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
- Data.Diverse.Type: type IndexOf (x :: k) (xs :: [k]) = IndexOfImpl xs x xs
- Data.Diverse.Type: type IsDistinct (xs :: [k]) = IsDistinctImpl xs xs
- Data.Diverse.Type: type KindAtIndex (n :: Nat) (xs :: [k]) = KindAtIndexImpl n xs n xs
- Data.Diverse.Type: type KindAtLabel (l :: k1) (xs :: [k]) = KindAtLabelImpl l xs xs
- Data.Diverse.Type: type MaybeMemberAt n x xs = (KnownNat n, KindAtPositionIs n x xs)
- Data.Diverse.Type: type MaybeUniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ PositionOf x xs)
- Data.Diverse.Type: type MemberAt n x xs = (KnownNat n, x ~ KindAtIndex n xs)
- Data.Diverse.Type: type PositionOf (x :: k) (xs :: [k]) = PositionOfImpl 0 x 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 SameLength (xs :: [k1]) (ys :: [k2]) = SameLengthImpl xs ys xs ys
- Data.Diverse.Type: type Unique (x :: k) (xs :: [k]) = UniqueImpl xs x xs
- Data.Diverse.Type: type UniqueLabel (l :: k1) (xs :: [k]) = UniqueLabelImpl xs l xs
- Data.Diverse.Type: type UniqueLabelMember l xs = (UniqueLabel l xs, KnownNat (IndexOf (KindAtLabel l xs) xs))
- Data.Diverse.Type: type UniqueMember x xs = (Unique x xs, KnownNat (IndexOf x xs))
- Data.Diverse.Type: type UniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ IndexOf x xs)
- Data.Diverse.Type: type WithoutIndex (n :: Nat) (xs :: [k]) = WithoutIndexImpl n xs n xs
- Data.Diverse.Type: type Zip (xs :: [k]) (ys :: [k]) = ZipImpl xs ys xs ys
- Data.Diverse.Which.Internal: instance (Data.Diverse.Case.Case (c n) (x : x' : xs) r, Data.Diverse.Reduce.Reduce Data.Diverse.Which.Internal.Which (Data.Diverse.Which.Internal.SwitchN c (n GHC.TypeLits.+ 1)) (x' : xs) r, Data.Diverse.Reiterate.ReiterateN c n (x : x' : xs)) => Data.Diverse.Reduce.Reduce Data.Diverse.Which.Internal.Which (Data.Diverse.Which.Internal.SwitchN c n) (x : x' : xs) r
- Data.Diverse.Which.Internal: instance (Data.Diverse.Case.Case c (x : x' : xs) r, Data.Diverse.Reduce.Reduce Data.Diverse.Which.Internal.Which (Data.Diverse.Which.Internal.Switch c) (x' : xs) r, Data.Diverse.Reiterate.Reiterate c (x : x' : xs)) => Data.Diverse.Reduce.Reduce Data.Diverse.Which.Internal.Which (Data.Diverse.Which.Internal.Switch c) (x : x' : xs) r
- Data.Diverse.Which.Internal: instance (Data.Diverse.Reduce.Reduce Data.Diverse.Which.Internal.Which (Data.Diverse.Which.Internal.Switch Data.Diverse.Which.Internal.CaseEqWhich) (x : xs) GHC.Types.Bool, Data.Diverse.Reduce.Reduce Data.Diverse.Which.Internal.Which (Data.Diverse.Which.Internal.Switch Data.Diverse.Which.Internal.CaseOrdWhich) (x : xs) GHC.Types.Ordering) => GHC.Classes.Ord (Data.Diverse.Which.Internal.Which (x : xs))
- Data.Diverse.Which.Internal: instance (Data.Diverse.Type.MaybeMemberAt n' x branch, n' ~ Data.Diverse.Type.PositionOf n indices) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseReinterpretN indices n) (x : tree) (GHC.Base.Maybe (Data.Diverse.Which.Internal.Which branch))
- Data.Diverse.Which.Internal: instance (Data.Diverse.Type.MaybeUniqueMemberAt n x branch, comp ~ Data.Diverse.Type.Complement tree branch, Data.Diverse.Type.MaybeUniqueMemberAt n' x comp, Data.Diverse.Type.Unique x tree) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseReinterpret branch tree) (x : tree') (Data.Either.Either (Data.Diverse.Which.Internal.Which comp) (Data.Diverse.Which.Internal.Which branch))
- Data.Diverse.Which.Internal: instance (Data.Diverse.Type.UniqueMember x tree, Data.Diverse.Type.Unique x branch) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseDiversify tree branch) (x : branch') (Data.Diverse.Which.Internal.Which tree)
- Data.Diverse.Which.Internal: instance Data.Diverse.Case.Case (c n) '[x] r => Data.Diverse.Reduce.Reduce Data.Diverse.Which.Internal.Which (Data.Diverse.Which.Internal.SwitchN c n) '[x] r
- Data.Diverse.Which.Internal: instance Data.Diverse.Case.Case c '[x] r => Data.Diverse.Reduce.Reduce Data.Diverse.Which.Internal.Which (Data.Diverse.Which.Internal.Switch c) '[x] r
- Data.Diverse.Which.Internal: instance Data.Diverse.Reduce.Reduce Data.Diverse.Which.Internal.Which (Data.Diverse.Which.Internal.Switch Data.Diverse.Which.Internal.CaseEqWhich) (x : xs) GHC.Types.Bool => GHC.Classes.Eq (Data.Diverse.Which.Internal.Which (x : xs))
- Data.Diverse.Which.Internal: instance Data.Diverse.Reduce.Reduce Data.Diverse.Which.Internal.Which (Data.Diverse.Which.Internal.Switch Data.Diverse.Which.Internal.CaseShowWhich) (x : xs) GHC.Show.ShowS => GHC.Show.Show (Data.Diverse.Which.Internal.Which (x : xs))
- Data.Diverse.Which.Internal: instance Data.Diverse.Type.MemberAt (Data.Diverse.Type.KindAtIndex n indices) x tree => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseDiversifyN indices n) (x : branch') (Data.Diverse.Which.Internal.Which tree)
+ Data.Diverse.CaseTypeable: instance Data.Typeable.Internal.Typeable (Data.Diverse.TypeLevel.Head xs) => Data.Diverse.Case.Case Data.Diverse.CaseTypeable.CaseTypeable xs r
+ Data.Diverse.Cases: instance Data.Diverse.TypeLevel.MemberAt n (Data.Diverse.TypeLevel.Head xs -> r) fs => Data.Diverse.Case.Case (Data.Diverse.Cases.CasesN fs n) xs r
+ Data.Diverse.Cases: instance Data.Diverse.TypeLevel.UniqueMember (Data.Diverse.TypeLevel.Head xs -> r) fs => Data.Diverse.Case.Case (Data.Diverse.Cases.Cases fs) xs r
+ Data.Diverse.Many.Internal: 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 n) (x : xs) (GHC.Base.Maybe (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny))
+ Data.Diverse.Many.Internal: 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 n) (x : xs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
+ Data.Diverse.Many.Internal: 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 n) ((x, y) : zs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
+ Data.Diverse.Many.Internal: instance (Data.Diverse.TypeLevel.UniqueIfExists smaller x larger, Data.Diverse.TypeLevel.MaybeUniqueMemberAt n x smaller) => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseSelect smaller larger) (x : xs) (GHC.Base.Maybe (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny))
+ Data.Diverse.Many.Internal: instance Data.Diverse.TypeLevel.UniqueMemberAt n x larger => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmend larger) (x : xs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
+ Data.Diverse.Many.Internal: instance Data.Diverse.TypeLevel.UniqueMemberAt n x larger => Data.Diverse.Many.Internal.CaseAny (Data.Diverse.Many.Internal.CaseAmend' larger) ((x, y) : zs) (GHC.Types.Int, Data.Diverse.Many.Internal.WrappedAny)
+ Data.Diverse.TypeLevel: type IndexOf (x :: k) (xs :: [k]) = IndexOfImpl xs x xs
+ Data.Diverse.TypeLevel: type IsDistinct (xs :: [k]) = IsDistinctImpl xs xs
+ Data.Diverse.TypeLevel: type KindAtIndex (n :: Nat) (xs :: [k]) = KindAtIndexImpl n xs n xs
+ Data.Diverse.TypeLevel: type KindAtLabel (l :: k1) (xs :: [k]) = KindAtLabelImpl l xs xs
+ Data.Diverse.TypeLevel: type MaybeMemberAt n x xs = (KnownNat n, KindAtPositionIs n x xs)
+ Data.Diverse.TypeLevel: type MaybeUniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ PositionOf x xs)
+ Data.Diverse.TypeLevel: type MemberAt n x xs = (KnownNat n, x ~ KindAtIndex n xs)
+ Data.Diverse.TypeLevel: type PositionOf (x :: k) (xs :: [k]) = PositionOfImpl 0 x xs
+ Data.Diverse.TypeLevel: type Replace (x :: k) (y :: k) (xs :: [k]) = ReplaceImpl x y xs
+ Data.Diverse.TypeLevel: type ReplaceIndex (n :: Nat) (y :: k) (xs :: [k]) = ReplaceIndexImpl n xs n y xs
+ Data.Diverse.TypeLevel: type Replaces (xs :: [k]) (ys :: [k]) (zs :: [k]) = ReplacesImpl xs ys xs ys zs
+ Data.Diverse.TypeLevel: type ReplacesIndex (ns :: [Nat]) (ys :: [k]) (xs :: [k]) = ReplacesIndexImpl 0 ns ys xs
+ Data.Diverse.TypeLevel: type SameLength (xs :: [k1]) (ys :: [k2]) = SameLengthImpl xs ys xs ys
+ Data.Diverse.TypeLevel: type Unique (x :: k) (xs :: [k]) = UniqueImpl xs x xs
+ Data.Diverse.TypeLevel: type UniqueLabel (l :: k1) (xs :: [k]) = UniqueLabelImpl xs l xs
+ Data.Diverse.TypeLevel: type UniqueLabelMember l xs = (UniqueLabel l xs, KnownNat (IndexOf (KindAtLabel l xs) xs))
+ Data.Diverse.TypeLevel: type UniqueMember x xs = (Unique x xs, KnownNat (IndexOf x xs))
+ Data.Diverse.TypeLevel: type UniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ IndexOf x xs)
+ Data.Diverse.TypeLevel: type WithoutIndex (n :: Nat) (xs :: [k]) = WithoutIndexImpl n xs n xs
+ Data.Diverse.TypeLevel: type Zip (xs :: [k]) (ys :: [k]) = ZipImpl xs ys xs ys
+ Data.Diverse.Which.Internal: instance (Data.Diverse.Case.Case (c n) (x : x' : xs) r, Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x' : xs)) (Data.Diverse.Which.Internal.SwitchN c (n GHC.TypeLits.+ 1) (x' : xs)) r, Data.Diverse.Reiterate.ReiterateN c n (x : x' : xs)) => Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : x' : xs)) (Data.Diverse.Which.Internal.SwitchN c n (x : x' : xs)) r
+ Data.Diverse.Which.Internal: instance (Data.Diverse.Case.Case c (x : x' : xs) r, Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x' : xs)) (Data.Diverse.Which.Internal.Switch c (x' : xs)) r, Data.Diverse.Reiterate.Reiterate c (x : x' : xs)) => Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : x' : xs)) (Data.Diverse.Which.Internal.Switch c (x : x' : xs)) r
+ Data.Diverse.Which.Internal: instance (Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : xs)) (Data.Diverse.Which.Internal.Switch Data.Diverse.Which.Internal.CaseEqWhich (x : xs)) GHC.Types.Bool, Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : xs)) (Data.Diverse.Which.Internal.Switch Data.Diverse.Which.Internal.CaseOrdWhich (x : xs)) GHC.Types.Ordering) => GHC.Classes.Ord (Data.Diverse.Which.Internal.Which (x : xs))
+ Data.Diverse.Which.Internal: 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 n) (x : tree) (GHC.Base.Maybe (Data.Diverse.Which.Internal.Which branch))
+ Data.Diverse.Which.Internal: instance (Data.Diverse.TypeLevel.MaybeUniqueMemberAt n x branch, comp ~ Data.Diverse.TypeLevel.Complement tree branch, Data.Diverse.TypeLevel.MaybeUniqueMemberAt n' x comp, Data.Diverse.TypeLevel.Unique x tree) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseReinterpret branch tree) (x : tree') (Data.Either.Either (Data.Diverse.Which.Internal.Which comp) (Data.Diverse.Which.Internal.Which branch))
+ Data.Diverse.Which.Internal: instance (Data.Diverse.TypeLevel.UniqueMember x tree, Data.Diverse.TypeLevel.Unique x branch) => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseDiversify tree branch) (x : branch') (Data.Diverse.Which.Internal.Which tree)
+ Data.Diverse.Which.Internal: instance Data.Diverse.Case.Case (c n) '[x] r => Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which '[x]) (Data.Diverse.Which.Internal.SwitchN c n '[x]) r
+ Data.Diverse.Which.Internal: instance Data.Diverse.Case.Case c '[x] r => Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which '[x]) (Data.Diverse.Which.Internal.Switch c '[x]) r
+ Data.Diverse.Which.Internal: instance Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : xs)) (Data.Diverse.Which.Internal.Switch Data.Diverse.Which.Internal.CaseEqWhich (x : xs)) GHC.Types.Bool => GHC.Classes.Eq (Data.Diverse.Which.Internal.Which (x : xs))
+ Data.Diverse.Which.Internal: instance Data.Diverse.Reduce.Reduce (Data.Diverse.Which.Internal.Which (x : xs)) (Data.Diverse.Which.Internal.Switch Data.Diverse.Which.Internal.CaseShowWhich (x : xs)) GHC.Show.ShowS => GHC.Show.Show (Data.Diverse.Which.Internal.Which (x : xs))
+ Data.Diverse.Which.Internal: instance Data.Diverse.TypeLevel.MemberAt (Data.Diverse.TypeLevel.KindAtIndex n indices) x tree => Data.Diverse.Case.Case (Data.Diverse.Which.Internal.CaseDiversifyN indices n) (x : branch') (Data.Diverse.Which.Internal.Which tree)
- Data.Diverse.Reduce: class Reduce v handler (xs :: [Type]) r
+ Data.Diverse.Reduce: class Reduce v handler r
- Data.Diverse.Reduce: reduce :: Reduce v handler xs r => handler xs r -> v xs -> r
+ Data.Diverse.Reduce: reduce :: Reduce v handler r => handler r -> v -> r
- Data.Diverse.Which: switch :: Reduce Which (Switch case') xs r => Which xs -> case' xs r -> r
+ Data.Diverse.Which: switch :: Reduce (Which xs) (Switch case' xs) r => Which xs -> case' xs r -> r
- Data.Diverse.Which: switchN :: Reduce Which (SwitchN case' n) xs r => Which xs -> case' n xs r -> r
+ Data.Diverse.Which: switchN :: Reduce (Which xs) (SwitchN case' n xs) r => Which xs -> case' n xs r -> r
- Data.Diverse.Which: type Diversify (tree :: [Type]) (branch :: [Type]) = Reduce Which (Switch (CaseDiversify tree branch)) branch (Which tree)
+ Data.Diverse.Which: type Diversify (tree :: [Type]) (branch :: [Type]) = Reduce (Which branch) (Switch (CaseDiversify tree branch) branch) (Which tree)
- Data.Diverse.Which: type DiversifyN (indices :: [Nat]) (tree :: [Type]) (branch :: [Type]) = (Reduce Which (SwitchN (CaseDiversifyN indices) 0) (KindsAtIndices indices tree) (Which tree), KindsAtIndices indices tree ~ branch)
+ Data.Diverse.Which: type DiversifyN (indices :: [Nat]) (tree :: [Type]) (branch :: [Type]) = (Reduce (Which branch) (SwitchN (CaseDiversifyN indices) 0 branch) (Which tree), KindsAtIndices indices tree ~ branch)
- Data.Diverse.Which: type Reinterpret branch tree = Reduce Which (Switch (CaseReinterpret branch tree)) tree (Either (Which (Complement tree branch)) (Which branch))
+ Data.Diverse.Which: type Reinterpret branch tree = Reduce (Which tree) (Switch (CaseReinterpret branch tree) tree) (Either (Which (Complement tree branch)) (Which branch))
- Data.Diverse.Which: type ReinterpretN (indices :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (Reduce Which (SwitchN (CaseReinterpretN indices) 0) tree (Maybe (Which (KindsAtIndices indices tree))), KindsAtIndices indices tree ~ branch)
+ Data.Diverse.Which: type ReinterpretN (indices :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (Reduce (Which tree) (SwitchN (CaseReinterpretN indices) 0 tree) (Maybe (Which branch)), KindsAtIndices indices tree ~ branch)
- Data.Diverse.Which: which :: Reduce Which (Switch case') xs r => case' xs r -> Which xs -> r
+ Data.Diverse.Which: which :: Reduce (Which xs) (Switch case' xs) r => case' xs r -> Which xs -> r
- Data.Diverse.Which: whichN :: Reduce Which (SwitchN case' n) xs r => case' n xs r -> Which xs -> r
+ Data.Diverse.Which: whichN :: Reduce (Which xs) (SwitchN case' n xs) r => case' n xs r -> Which xs -> r
- Data.Diverse.Which.Internal: switch :: Reduce Which (Switch case') xs r => Which xs -> case' xs r -> r
+ Data.Diverse.Which.Internal: switch :: Reduce (Which xs) (Switch case' xs) r => Which xs -> case' xs r -> r
- Data.Diverse.Which.Internal: switchN :: Reduce Which (SwitchN case' n) xs r => Which xs -> case' n xs r -> r
+ Data.Diverse.Which.Internal: switchN :: Reduce (Which xs) (SwitchN case' n xs) r => Which xs -> case' n xs r -> r
- Data.Diverse.Which.Internal: type Diversify (tree :: [Type]) (branch :: [Type]) = Reduce Which (Switch (CaseDiversify tree branch)) branch (Which tree)
+ Data.Diverse.Which.Internal: type Diversify (tree :: [Type]) (branch :: [Type]) = Reduce (Which branch) (Switch (CaseDiversify tree branch) branch) (Which tree)
- Data.Diverse.Which.Internal: type DiversifyN (indices :: [Nat]) (tree :: [Type]) (branch :: [Type]) = (Reduce Which (SwitchN (CaseDiversifyN indices) 0) (KindsAtIndices indices tree) (Which tree), KindsAtIndices indices tree ~ branch)
+ Data.Diverse.Which.Internal: type DiversifyN (indices :: [Nat]) (tree :: [Type]) (branch :: [Type]) = (Reduce (Which branch) (SwitchN (CaseDiversifyN indices) 0 branch) (Which tree), KindsAtIndices indices tree ~ branch)
- Data.Diverse.Which.Internal: type Reinterpret branch tree = Reduce Which (Switch (CaseReinterpret branch tree)) tree (Either (Which (Complement tree branch)) (Which branch))
+ Data.Diverse.Which.Internal: type Reinterpret branch tree = Reduce (Which tree) (Switch (CaseReinterpret branch tree) tree) (Either (Which (Complement tree branch)) (Which branch))
- Data.Diverse.Which.Internal: type ReinterpretN (indices :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (Reduce Which (SwitchN (CaseReinterpretN indices) 0) tree (Maybe (Which (KindsAtIndices indices tree))), KindsAtIndices indices tree ~ branch)
+ Data.Diverse.Which.Internal: type ReinterpretN (indices :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (Reduce (Which tree) (SwitchN (CaseReinterpretN indices) 0 tree) (Maybe (Which branch)), KindsAtIndices indices tree ~ branch)
- Data.Diverse.Which.Internal: which :: Reduce Which (Switch case') xs r => case' xs r -> Which xs -> r
+ Data.Diverse.Which.Internal: which :: Reduce (Which xs) (Switch case' xs) r => case' xs r -> Which xs -> r
- Data.Diverse.Which.Internal: whichN :: Reduce Which (SwitchN case' n) xs r => case' n xs r -> Which xs -> r
+ Data.Diverse.Which.Internal: whichN :: Reduce (Which xs) (SwitchN case' n xs) r => case' n xs r -> Which xs -> r

Files

README.md view
@@ -5,7 +5,7 @@  "Data.Diverse.Which" polymorphic variant of possibilities encoded as (Int, Any). -Provides getters, setters, projection, injection, fold, and catamorphisms;-accessed by type or index.+Provides getters, setters, projection, injection, folds, and catamorphisms;+accessed by type or index or label.  Refer to [ManySpec.hs](https://github.com/louispan/data-diverse/blob/master/test/Data/Diverse/ManySpec.hs) and [WhichSpec.hs](https://github.com/louispan/data-diverse/blob/master/test/Data/Diverse/WhichSpec.hs) for example usages.
data-diverse.cabal view
@@ -1,10 +1,10 @@ name:                data-diverse-version:             0.4.0.0+version:             0.5.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).-                     Provides getters, setters, projection, injection, fold, and catamorphisms;-                     accessed by type or index.+                     Provides getters, setters, projection, injection, folds, and catamorphisms;+                     accessed by type, index or label.                      Refer to [ManySpec.hs](https://github.com/louispan/data-diverse/blob/master/test/Data/Diverse/ManySpec.hs) and [WhichSpec.hs](https://github.com/louispan/data-diverse/blob/master/test/Data/Diverse/WhichSpec.hs) for example usages. homepage:            https://github.com/louispan/data-diverse#readme license:             BSD3@@ -16,7 +16,7 @@ build-type:          Simple extra-source-files:  README.md cabal-version:       >=1.10-tested-with:         GHC == 8.0.1+tested-with:         GHC == 8.0.2  library   hs-source-dirs:      src@@ -29,10 +29,10 @@                        Data.Diverse.Many.Internal                        Data.Diverse.Reduce                        Data.Diverse.Reiterate-                       Data.Diverse.Type+                       Data.Diverse.TypeLevel+                       Data.Diverse.TypeLevel.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
src/Data/Diverse.hs view
@@ -6,7 +6,7 @@     , module Data.Diverse.Many     , module Data.Diverse.Reduce     , module Data.Diverse.Reiterate-    , module Data.Diverse.Type+    , module Data.Diverse.TypeLevel     , module Data.Diverse.Which     ) where @@ -17,5 +17,5 @@ import Data.Diverse.Many import Data.Diverse.Reduce import Data.Diverse.Reiterate-import Data.Diverse.Type+import Data.Diverse.TypeLevel import Data.Diverse.Which
src/Data/Diverse/Case.hs view
@@ -6,7 +6,7 @@  module Data.Diverse.Case where -import Data.Diverse.Type+import Data.Diverse.TypeLevel import Data.Kind  -- | This class allows defining handlers that can handle the 'Head' type in the @xs@ typelist.
src/Data/Diverse/CaseTypeable.hs view
@@ -9,7 +9,7 @@  import Data.Diverse.Case import Data.Diverse.Reiterate-import Data.Diverse.Type+import Data.Diverse.TypeLevel import Data.Kind import Data.Typeable 
src/Data/Diverse/Cases.hs view
@@ -21,7 +21,7 @@ import Data.Diverse.Case import Data.Diverse.Many import Data.Diverse.Reiterate-import Data.Diverse.Type+import Data.Diverse.TypeLevel import Data.Kind import Data.Proxy import GHC.TypeLits
src/Data/Diverse/Many/Internal.hs view
@@ -103,7 +103,7 @@ import Data.Diverse.AFoldable import Data.Diverse.Case import Data.Diverse.Reiterate-import Data.Diverse.Type+import Data.Diverse.TypeLevel import Data.Kind import qualified Data.Map.Strict as M import Data.Proxy
src/Data/Diverse/Reduce.hs view
@@ -1,12 +1,9 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-}  module Data.Diverse.Reduce where -import Data.Kind---- | Reduce a polymorphic variant @v xs@ into @r@ using handlers.+-- | 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 (xs :: [Type]) r where-    reduce :: handler xs r -> v xs -> r+class Reduce v handler r where+    reduce :: handler r -> v -> r
src/Data/Diverse/Reiterate.hs view
@@ -6,7 +6,7 @@  module Data.Diverse.Reiterate where -import Data.Diverse.Type+import Data.Diverse.TypeLevel import Data.Kind import GHC.TypeLits 
− src/Data/Diverse/Type.hs
@@ -1,145 +0,0 @@-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE TypeInType #-}--module Data.Diverse.Type where--import Data.Diverse.Type.Internal-import Data.Kind-import GHC.TypeLits---- | Ensures that @x@ is a unique member of @xs@, and that 'natVal' can be used.-type UniqueMember x xs = (Unique x xs, KnownNat (IndexOf x xs))---- | Ensures that @x@ is a unique member of @xs@, and that 'natVal' can be used.-type UniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ IndexOf x xs)---- | Ensures that @x@ is a unique member of @xs@, and that 'natVal' can be used.-type UniqueLabelMember l xs = (UniqueLabel l xs, KnownNat (IndexOf (KindAtLabel l xs) xs))---- | Ensures that @x@ is a unique member of @xs@ if it exists, and that 'natVal' can be used.-type MaybeUniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ PositionOf x xs)---- | Ensures that @x@ is a member of @xs@ at @n@, and that 'natVal' can be used.-type MemberAt n x xs = (KnownNat n, x ~ KindAtIndex n xs)---- | 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)---- | Ensures x is a unique member in @xs@ iff it exists in @ys@-type family UniqueIfExists ys x xs :: Constraint where-    UniqueIfExists '[] x xs = ()-    UniqueIfExists (y ': ys) y xs = Unique y xs-    UniqueIfExists (y ': ys) x xs = UniqueIfExists ys x xs---- | Ensures that the type list contain unique types-type IsDistinct (xs :: [k]) = IsDistinctImpl xs xs---- | Return the list of distinct types in a typelist-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---- | Ensures that the @label@ in @tagged label v@ only ever appears once in @xs@.-type UniqueLabel (l :: k1) (xs :: [k]) = UniqueLabelImpl xs l xs---- | Ensures that the @label@ list all 'UniqueLabel's-type family UniqueLabels (ls :: [k1]) (xs :: [k]) :: Constraint where-    UniqueLabels '[] xs = ()-    UniqueLabels (l ': ls) xs = (UniqueLabel l xs, UniqueLabels ls xs)---- | Get the first index of a type (Indexed by 0)--- Will result in type error if x doesn't exist in xs.-type IndexOf (x :: k) (xs :: [k]) = IndexOfImpl xs x xs---- | 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-type family KindAtPositionIs (n :: Nat) (x :: k) (xs :: [k]) :: Constraint where-    KindAtPositionIs 0 x xs = ()-    KindAtPositionIs n x xs = (x ~ KindAtIndexImpl (n - 1) xs (n - 1) xs)---- | Get the types at an list of index-type family KindsAtIndices (ns :: [Nat]) (xs :: [k]) :: [k] where-    KindsAtIndices '[] xs = '[]-    KindsAtIndices (n ': ns) xs = KindAtIndex n xs ': KindsAtIndices ns xs--type family KindsAtLabels (ls :: [k1]) (xs :: [k]) :: [k] where-    KindsAtLabels '[] xs = '[]-    KindsAtLabels (l ': ls) xs = KindAtLabel l xs ': KindsAtLabels ls xs---- | The typelist @xs@ without first @x@. It is okay for @x@ not to exist in @xs@-type family Without (x :: k) (xs :: [k]) :: [k] where-    Without x '[] = '[]-    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---- | 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 "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 "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 "Last error: empty type list")-    Last (x ': x' ': xs) = Last (x' ': xs)-    Last '[x] = x---- | 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@.-type family Complement (xs :: [k]) (ys :: [k]) :: [k] where-    Complement xs '[] = xs-    Complement xs (y ': ys)  = Complement (Without y xs) ys---- | Returns a @xs@ appended with @ys@-type family Append (xs :: [k]) (ys :: [k]) :: [k] where-    Append '[] ys = ys-    Append (x ': xs) ys = x ': Append xs ys---- | Returns the typelist without the 'Last' type-type family Init (xs :: [k]) :: [k] where-    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
@@ -1,194 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE UndecidableInstances #-}--module Data.Diverse.Type.Internal where--import Data.Kind-import GHC.TypeLits---- | Get the first position of a type (indexed by 1)--- Will return 0 if @x@ doesn't exists in @xs@.-type family PositionOfImpl (i :: Nat) (x :: k) (xs :: [k]) :: Nat where-   PositionOfImpl i x (x ': xs) = i + 1-   PositionOfImpl i y (x ': xs) = PositionOfImpl (i + 1) y xs-   PositionOfImpl i x '[] = 0---- | Get the first index of a type from a list-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 "IndexOf error: ‘"-                                      ':<>: 'ShowType y-                                      ':<>: 'Text "’"-                                      ':<>: 'Text " is not a member of "-                                      ':<>: 'Text "‘"-                                      ':<>: 'ShowType ctx-                                      ':<>: 'Text "’")---- | 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 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 "Not unique error: ‘"-                                             ':<>: 'ShowType x-                                             ':<>: 'Text "’"-                                             ':<>: 'Text " is a duplicate in "-                                             ':<>: 'Text "‘"-                                             ':<>: 'ShowType ctx-                                             ':<>: 'Text "’")-    MissingImpl ctx y (x ': xs) = (MissingImpl ctx y xs)---- | Errors if a label exists in a typelist-type family MissingLabelImpl (ctx :: [k]) (l :: k2) (xs :: [k]) :: Constraint where-    MissingLabelImpl ctx y '[] = ()-    MissingLabelImpl ctx l (tagged l x ': xs) = TypeError ('Text "Not unique label error: ‘"-                                             ':<>: 'ShowType l-                                             ':<>: 'Text "’"-                                             ':<>: 'Text " is a duplicate in "-                                             ':<>: 'Text "‘"-                                             ':<>: 'ShowType ctx-                                             ':<>: 'Text "’")-    MissingLabelImpl ctx l (x ': xs) = (MissingLabelImpl ctx l xs)---- | Ensures that the type list contain unique types.--- Not implemented as @(xs ~ Nub xs)@ for better type error messages.-type family IsDistinctImpl (ctx :: [k]) (xs :: [k]) :: Constraint where-    IsDistinctImpl ctx '[] = ()-    IsDistinctImpl ctx (x ': xs) = (MissingImpl ctx x xs, IsDistinctImpl ctx xs)---- | Ensures that @x@ only ever appears once in @xs@-type family UniqueImpl (ctx :: [k]) (x :: k) (xs :: [k]) :: Constraint where-    UniqueImpl ctx x '[] = ()-    UniqueImpl ctx x (x ': xs) = MissingImpl ctx x xs-    UniqueImpl ctx x (y ': xs) = UniqueImpl ctx x xs---- | Ensures that the @label@ in @tagged label v@ only ever appears once in @xs@.-type family UniqueLabelImpl (ctx :: [k]) (l :: k1) (xs :: [k]) :: Constraint where-    UniqueLabelImpl ctx l '[] = ()-    UniqueLabelImpl ctx l (tagged l x ': xs) = MissingLabelImpl ctx l xs-    UniqueLabelImpl ctx l (y ': xs) = UniqueLabelImpl ctx l xs---- | Indexed access into the list-type family KindAtIndexImpl (orig :: Nat) (ctx :: [k]) (n :: Nat) (xs :: [k]) :: k where-    KindAtIndexImpl i ctx 0 '[] = TypeError ('Text "KindAtIndex error: Index ‘"-                                       ':<>: 'ShowType i-                                       ':<>: 'Text "’"-                                       ':<>: 'Text " is out of bounds of "-                                       ':<>: 'Text "‘"-                                       ':<>: 'ShowType ctx-                                       ':<>: 'Text "’")-    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 :: [k]) (xs :: [k]) :: k 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 "SameLength error: ‘"-                                            ':<>: 'ShowType as-                                            ':<>: 'Text "’"-                                            ':<>: 'Text " is not the same length as "-                                            ':<>: 'Text "‘"-                                            ':<>: 'ShowType bs-                                            ':<>: 'Text "’")---- | 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 "WithoutIndex error: Index ‘"-                                       ':<>: 'ShowType i-                                       ':<>: 'Text "’"-                                       ':<>: 'Text " is out of bounds of "-                                       ':<>: 'Text "‘"-                                       ':<>: 'ShowType ctx-                                       ':<>: '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/TypeLevel.hs view
@@ -0,0 +1,145 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE TypeInType #-}++module Data.Diverse.TypeLevel where++import Data.Diverse.TypeLevel.Internal+import Data.Kind+import GHC.TypeLits++-- | Ensures that @x@ is a unique member of @xs@, and that 'natVal' can be used.+type UniqueMember x xs = (Unique x xs, KnownNat (IndexOf x xs))++-- | Ensures that @x@ is a unique member of @xs@, and that 'natVal' can be used.+type UniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ IndexOf x xs)++-- | Ensures that @x@ is a unique member of @xs@, and that 'natVal' can be used.+type UniqueLabelMember l xs = (UniqueLabel l xs, KnownNat (IndexOf (KindAtLabel l xs) xs))++-- | Ensures that @x@ is a unique member of @xs@ if it exists, and that 'natVal' can be used.+type MaybeUniqueMemberAt n x xs = (Unique x xs, KnownNat n, n ~ PositionOf x xs)++-- | Ensures that @x@ is a member of @xs@ at @n@, and that 'natVal' can be used.+type MemberAt n x xs = (KnownNat n, x ~ KindAtIndex n xs)++-- | 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)++-- | Ensures x is a unique member in @xs@ iff it exists in @ys@+type family UniqueIfExists ys x xs :: Constraint where+    UniqueIfExists '[] x xs = ()+    UniqueIfExists (y ': ys) y xs = Unique y xs+    UniqueIfExists (y ': ys) x xs = UniqueIfExists ys x xs++-- | Ensures that the type list contain unique types+type IsDistinct (xs :: [k]) = IsDistinctImpl xs xs++-- | Return the list of distinct types in a typelist+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++-- | Ensures that the @label@ in @tagged label v@ only ever appears once in @xs@.+type UniqueLabel (l :: k1) (xs :: [k]) = UniqueLabelImpl xs l xs++-- | Ensures that the @label@ list all 'UniqueLabel's+type family UniqueLabels (ls :: [k1]) (xs :: [k]) :: Constraint where+    UniqueLabels '[] xs = ()+    UniqueLabels (l ': ls) xs = (UniqueLabel l xs, UniqueLabels ls xs)++-- | Get the first index of a type (Indexed by 0)+-- Will result in type error if x doesn't exist in xs.+type IndexOf (x :: k) (xs :: [k]) = IndexOfImpl xs x xs++-- | 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+type family KindAtPositionIs (n :: Nat) (x :: k) (xs :: [k]) :: Constraint where+    KindAtPositionIs 0 x xs = ()+    KindAtPositionIs n x xs = (x ~ KindAtIndexImpl (n - 1) xs (n - 1) xs)++-- | Get the types at an list of index+type family KindsAtIndices (ns :: [Nat]) (xs :: [k]) :: [k] where+    KindsAtIndices '[] xs = '[]+    KindsAtIndices (n ': ns) xs = KindAtIndex n xs ': KindsAtIndices ns xs++type family KindsAtLabels (ls :: [k1]) (xs :: [k]) :: [k] where+    KindsAtLabels '[] xs = '[]+    KindsAtLabels (l ': ls) xs = KindAtLabel l xs ': KindsAtLabels ls xs++-- | The typelist @xs@ without first @x@. It is okay for @x@ not to exist in @xs@+type family Without (x :: k) (xs :: [k]) :: [k] where+    Without x '[] = '[]+    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++-- | 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 "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 "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 "Last error: empty type list")+    Last (x ': x' ': xs) = Last (x' ': xs)+    Last '[x] = x++-- | 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@.+type family Complement (xs :: [k]) (ys :: [k]) :: [k] where+    Complement xs '[] = xs+    Complement xs (y ': ys)  = Complement (Without y xs) ys++-- | Returns a @xs@ appended with @ys@+type family Append (xs :: [k]) (ys :: [k]) :: [k] where+    Append '[] ys = ys+    Append (x ': xs) ys = x ': Append xs ys++-- | Returns the typelist without the 'Last' type+type family Init (xs :: [k]) :: [k] where+    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/TypeLevel/Internal.hs view
@@ -0,0 +1,194 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Data.Diverse.TypeLevel.Internal where++import Data.Kind+import GHC.TypeLits++-- | Get the first position of a type (indexed by 1)+-- Will return 0 if @x@ doesn't exists in @xs@.+type family PositionOfImpl (i :: Nat) (x :: k) (xs :: [k]) :: Nat where+   PositionOfImpl i x (x ': xs) = i + 1+   PositionOfImpl i y (x ': xs) = PositionOfImpl (i + 1) y xs+   PositionOfImpl i x '[] = 0++-- | Get the first index of a type from a list+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 "IndexOf error: ‘"+                                      ':<>: 'ShowType y+                                      ':<>: 'Text "’"+                                      ':<>: 'Text " is not a member of "+                                      ':<>: 'Text "‘"+                                      ':<>: 'ShowType ctx+                                      ':<>: 'Text "’")++-- | 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 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 "Not unique error: ‘"+                                             ':<>: 'ShowType x+                                             ':<>: 'Text "’"+                                             ':<>: 'Text " is a duplicate in "+                                             ':<>: 'Text "‘"+                                             ':<>: 'ShowType ctx+                                             ':<>: 'Text "’")+    MissingImpl ctx y (x ': xs) = (MissingImpl ctx y xs)++-- | Errors if a label exists in a typelist+type family MissingLabelImpl (ctx :: [k]) (l :: k2) (xs :: [k]) :: Constraint where+    MissingLabelImpl ctx y '[] = ()+    MissingLabelImpl ctx l (tagged l x ': xs) = TypeError ('Text "Not unique label error: ‘"+                                             ':<>: 'ShowType l+                                             ':<>: 'Text "’"+                                             ':<>: 'Text " is a duplicate in "+                                             ':<>: 'Text "‘"+                                             ':<>: 'ShowType ctx+                                             ':<>: 'Text "’")+    MissingLabelImpl ctx l (x ': xs) = (MissingLabelImpl ctx l xs)++-- | Ensures that the type list contain unique types.+-- Not implemented as @(xs ~ Nub xs)@ for better type error messages.+type family IsDistinctImpl (ctx :: [k]) (xs :: [k]) :: Constraint where+    IsDistinctImpl ctx '[] = ()+    IsDistinctImpl ctx (x ': xs) = (MissingImpl ctx x xs, IsDistinctImpl ctx xs)++-- | Ensures that @x@ only ever appears once in @xs@+type family UniqueImpl (ctx :: [k]) (x :: k) (xs :: [k]) :: Constraint where+    UniqueImpl ctx x '[] = ()+    UniqueImpl ctx x (x ': xs) = MissingImpl ctx x xs+    UniqueImpl ctx x (y ': xs) = UniqueImpl ctx x xs++-- | Ensures that the @label@ in @tagged label v@ only ever appears once in @xs@.+type family UniqueLabelImpl (ctx :: [k]) (l :: k1) (xs :: [k]) :: Constraint where+    UniqueLabelImpl ctx l '[] = ()+    UniqueLabelImpl ctx l (tagged l x ': xs) = MissingLabelImpl ctx l xs+    UniqueLabelImpl ctx l (y ': xs) = UniqueLabelImpl ctx l xs++-- | Indexed access into the list+type family KindAtIndexImpl (orig :: Nat) (ctx :: [k]) (n :: Nat) (xs :: [k]) :: k where+    KindAtIndexImpl i ctx 0 '[] = TypeError ('Text "KindAtIndex error: Index ‘"+                                       ':<>: 'ShowType i+                                       ':<>: 'Text "’"+                                       ':<>: 'Text " is out of bounds of "+                                       ':<>: 'Text "‘"+                                       ':<>: 'ShowType ctx+                                       ':<>: 'Text "’")+    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 :: [k]) (xs :: [k]) :: k 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 "SameLength error: ‘"+                                            ':<>: 'ShowType as+                                            ':<>: 'Text "’"+                                            ':<>: 'Text " is not the same length as "+                                            ':<>: 'Text "‘"+                                            ':<>: 'ShowType bs+                                            ':<>: 'Text "’")++-- | 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 "WithoutIndex error: Index ‘"+                                       ':<>: 'ShowType i+                                       ':<>: 'Text "’"+                                       ':<>: 'Text " is out of bounds of "+                                       ':<>: 'Text "‘"+                                       ':<>: 'ShowType ctx+                                       ':<>: '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
@@ -70,7 +70,7 @@ import Data.Diverse.Case import Data.Diverse.Reduce import Data.Diverse.Reiterate-import Data.Diverse.Type+import Data.Diverse.TypeLevel import Data.Kind import Data.Proxy import qualified GHC.Generics as G@@ -322,7 +322,7 @@ ------------------------------------------------------------------  -- | A friendlier constraint synonym for 'diversify'.-type Diversify (tree :: [Type]) (branch :: [Type]) = Reduce Which (Switch (CaseDiversify tree branch)) branch (Which tree)+type Diversify (tree :: [Type]) (branch :: [Type]) = Reduce (Which branch) (Switch (CaseDiversify tree branch) branch) (Which tree)  -- | Convert a 'Which' to another 'Which' that may include other possibilities. -- That is, @branch@ is equal or is a subset of @tree@.@@ -378,7 +378,9 @@ ------------------------------------------------------------------  -- | A friendlier constraint synonym for 'diversifyN'.-type DiversifyN (indices :: [Nat]) (tree :: [Type]) (branch :: [Type]) = (Reduce Which (SwitchN (CaseDiversifyN indices) 0) (KindsAtIndices indices tree) (Which tree), KindsAtIndices indices tree ~ branch)+type DiversifyN (indices :: [Nat]) (tree :: [Type]) (branch :: [Type]) =+    ( Reduce (Which branch) (SwitchN (CaseDiversifyN indices) 0 branch) (Which tree)+    , KindsAtIndices indices tree ~ branch)  -- | A variation of 'diversify' which uses a Nat list @indices@ to specify how to reorder the fields, where --@@ -410,7 +412,7 @@ ------------------------------------------------------------------  -- | A friendlier constraint synonym for 'reinterpret'.-type Reinterpret branch tree = Reduce Which (Switch (CaseReinterpret branch tree)) tree (Either (Which (Complement tree branch)) (Which branch))+type Reinterpret branch tree = Reduce (Which tree) (Switch (CaseReinterpret branch tree) tree) (Either (Which (Complement tree branch)) (Which branch))  -- | 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 'Left'over @compliment@ types.@@ -472,7 +474,9 @@ ------------------------------------------------------------------  -- | A friendlier constraint synonym for 'reinterpretN'.-type ReinterpretN (indices :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (Reduce Which (SwitchN (CaseReinterpretN indices) 0) tree (Maybe (Which (KindsAtIndices indices tree))), KindsAtIndices indices tree ~ branch)+type ReinterpretN (indices :: [Nat]) (branch :: [Type]) (tree :: [Type]) =+    ( Reduce (Which tree) (SwitchN (CaseReinterpretN indices) 0 tree) (Maybe (Which branch))+    , KindsAtIndices indices tree ~ branch)  -- | A limited variation of 'reinterpret' which uses a Nat list @n@ to specify how to reorder the fields, where --@@ -571,24 +575,26 @@  -- | 'trial0' each type in a 'Which', and either handle the 'case'' with value discovered, or __'reiterate'__ -- trying the next type in the type list.-instance (Case c (x ': x' ': xs) r, Reduce Which (Switch c) (x' ': xs) r, Reiterate c (x : x' : xs)) =>-         Reduce Which (Switch c) (x ': x' ': xs) r where+instance (Case c (x ': x' ': xs) r, Reduce (Which (x' ': xs)) (Switch c (x' ': xs)) r, Reiterate c (x : x' : xs)) =>+         Reduce (Which (x ': x' ': xs)) (Switch c (x ': x' ': xs)) r where     reduce (Switch c) v =         case trial0 v of             Right a -> case' c a             Left v' -> reduce (Switch (reiterate c)) v'     -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE reduce #-}+    -- Using INLINEABLE instead of NOLINE so that ghc 8.2.1 can optimize to single case statement+    -- See https://ghc.haskell.org/trac/ghc/ticket/12877+    {-# INLINEABLE reduce #-}  -- | Terminating case of the loop, ensuring that a instance of @Case '[]@ -- with an empty typelist is not required. -- You can't reduce 'impossible'-instance (Case c '[x] r) => Reduce Which (Switch c) '[x] r where+instance (Case c '[x] r) => Reduce (Which '[x]) (Switch c '[x]) r where     reduce (Switch c) v = case obvious v of             a -> case' c a  -- | Catamorphism for 'Which'. This is equivalent to @flip 'switch'@.-which :: Reduce Which (Switch case') xs r => case' xs r -> Which xs -> r+which :: Reduce (Which xs) (Switch case' xs) r => case' xs r -> Which xs -> r which = reduce . Switch  -- | A switch/case statement for 'Which'. This is equivalent to @flip 'which'@@@ -611,7 +617,7 @@ -- @ -- -- Or you may use your own custom instance of 'Case'.-switch :: Reduce Which (Switch case') xs r => Which xs -> case' xs r -> r+switch :: Reduce (Which xs) (Switch case' xs) r => Which xs -> case' xs r -> r switch = flip which  ------------------------------------------------------------------@@ -622,24 +628,26 @@  -- | 'trial0' each type in a 'Which', and either handle the 'case'' with value discovered, or __'reiterateN'__ -- trying the next type in the type list.-instance (Case (c n) (x ': x' ': xs) r, Reduce Which (SwitchN c (n + 1)) (x' ': xs) r, ReiterateN c n (x : x' : xs)) =>-         Reduce Which (SwitchN c n) (x ': x' ': xs) r where+instance (Case (c n) (x ': x' ': xs) r, Reduce (Which (x' ': xs)) (SwitchN c (n + 1) (x' ': xs)) r, ReiterateN c n (x : x' : xs)) =>+         Reduce (Which (x ': x' ': xs)) (SwitchN c n (x ': x' ': xs)) r where     reduce (SwitchN c) v =         case trial0 v of             Right a -> case' c a             Left v' -> reduce (SwitchN (reiterateN c)) v'     -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE reduce #-}+    -- Using INLINEABLE instead of NOLINE so that ghc 8.2.1 can optimize to single case statement+    -- See https://ghc.haskell.org/trac/ghc/ticket/12877+    {-# INLINEABLE reduce #-}  -- | Terminating case of the loop, ensuring that a instance of @Case '[]@ -- with an empty typelist is not required. -- You can't reduce 'impossible'-instance (Case (c n) '[x] r) => Reduce Which (SwitchN c n) '[x] r where+instance (Case (c n) '[x] r) => Reduce (Which '[x]) (SwitchN c n '[x]) r where     reduce (SwitchN c) v = case obvious v of             a -> case' c a  -- | Catamorphism for 'Which'. This is equivalent to @flip 'switchN'@.-whichN :: Reduce Which (SwitchN case' n) xs r => case' n xs r -> Which xs -> r+whichN :: Reduce (Which xs) (SwitchN case' n xs) r => case' n xs r -> Which xs -> r whichN = reduce . SwitchN  -- | A switch/case statement for 'Which'. This is equivalent to @flip 'whichN'@@@ -658,13 +666,13 @@ -- @ -- -- Or you may use your own custom instance of 'Case'.-switchN :: Reduce Which (SwitchN case' n) xs r => Which xs -> case' n xs r -> r+switchN :: Reduce (Which xs) (SwitchN case' n xs) r => Which xs -> case' n xs r -> r switchN = flip whichN  -----------------------------------------------------------------  -- | Two 'Which'es are only equal iff they both contain the equivalnet value at the same type index.-instance (Reduce Which (Switch CaseEqWhich) (x ': xs) Bool) => Eq (Which (x ': xs)) where+instance (Reduce (Which (x ': xs)) (Switch CaseEqWhich (x ': xs)) Bool) => Eq (Which (x ': xs)) where     l@(Which i _) == (Which j u) =         if i /= j             then False@@ -687,7 +695,10 @@ -----------------------------------------------------------------  -- | A 'Which' with a type at smaller type index is considered smaller.-instance (Reduce Which (Switch CaseEqWhich) (x ': xs) Bool, Reduce Which (Switch CaseOrdWhich) (x ': xs) Ordering) => Ord (Which (x ': xs)) where+instance ( Reduce (Which (x ': xs)) (Switch CaseEqWhich (x ': xs)) Bool+         , Reduce (Which (x ': xs)) (Switch CaseOrdWhich (x ': xs)) Ordering+         ) =>+         Ord (Which (x ': xs)) where     compare l@(Which i _) (Which j u) =         if i /= j             then compare i j@@ -710,7 +721,7 @@ ------------------------------------------------------------------  -- | @show ('pick'' \'A') == "pick \'A'"@-instance (Reduce Which (Switch CaseShowWhich) (x ': xs) ShowS) => Show (Which (x ': xs)) where+instance (Reduce (Which (x ': xs)) (Switch CaseShowWhich (x ': xs)) ShowS) => Show (Which (x ': xs)) where     showsPrec d v = showParen (d > app_prec) (which (CaseShowWhich 0) v)       where app_prec = 10 @@ -750,7 +761,9 @@     whichReadPrec i j = readWhich_ i j                <|> (diversify0' <$> (whichReadPrec i (j + 1) :: ReadPrec (Which_ (x' ': xs))))     -- GHC compilation is SLOW if there is no pragma for recursive typeclass functions for different types-    {-# NOINLINE whichReadPrec #-}+    -- Using INLINEABLE instead of NOLINE so that ghc 8.2.1 can optimize to single case statement+    -- See https://ghc.haskell.org/trac/ghc/ticket/12877+    {-# INLINEABLE whichReadPrec #-}   -- | This 'Read' instance tries to read using the each type in the typelist, using the first successful type read.
test/Data/Diverse/TypeSpec.hs view
@@ -29,7 +29,7 @@             fromIntegral (natVal @(PositionOf Int '[Bool, String, Char]) Proxy) `shouldBe` (0 :: Int)          it "ComplementOf" $ do-            let complementTest :: (Complement xs ys ~ comp) => Proxy xs -> Proxy ys -> Proxy comp -> Proxy comp+            let complementTest :: Proxy xs -> Proxy ys -> Proxy (Complement xs ys) -> Proxy (Complement xs ys)                 complementTest _ _ comp = comp              complementTest (Proxy @[String, Int]) (Proxy @[Bool, Int]) (Proxy @'[String]) `shouldBe` Proxy