packages feed

haskus-utils-variant 2.0.3 → 2.1

raw patch · 5 files changed

+387/−349 lines, 5 filesdep ~haskus-utils-types

Dependency ranges changed: haskus-utils-types

Files

haskus-utils-variant.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.20 name: haskus-utils-variant-version: 2.0.3+version: 2.1 license: BSD3 license-file: LICENSE copyright: Sylvain Henry 2018@@ -25,6 +25,7 @@         Haskus.Utils.Variant.Flow         Haskus.Utils.Variant.Cont         Haskus.Utils.Variant.Syntax+        Haskus.Utils.VariantF         Haskus.Utils.EADT         Haskus.Utils.EADT.TH     hs-source-dirs: src/lib@@ -33,7 +34,7 @@     build-depends:         base >=4.9 && <4.12,         template-haskell >=2.13.0.0 && <2.14,-        haskus-utils-types ==1.1.*,+        haskus-utils-types ==1.2.*,         haskus-utils-data ==1.1.*  test-suite tests
src/lib/Haskus/Utils/EADT.hs view
@@ -8,37 +8,13 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE RankNTypes #-}-{-# LANGUAGE MultiParamTypeClasses #-}  -- | Extensible ADT module Haskus.Utils.EADT-   ( VariantF (..)-   , ApplyAll-   , pattern FV-   , appendVariantF-   , toVariantFHead-   , toVariantFTail-   , popVariantFHead-   , popVariantF-   , mapVariantF-   , variantFToValue-   , LiftableF-   , liftVariantF-   , AlterVariantF-   , alterVariantF-   , AlgVariantF-   , algVariantF-   , splitVariantF-   , variantFToCont-   , variantFToContM-   , contToVariantF-   , contToVariantFM-   -- * Extensible ADT-   , EADT+   ( EADT    , (:<:)    , (:<<:)    , pattern VF@@ -54,222 +30,19 @@    , contToEADT    , contToEADTM    -- * Reexport-   , NoConstraint    , module Haskus.Utils.Functor+   , module Haskus.Utils.VariantF    ) where +import Haskus.Utils.VariantF import Haskus.Utils.Variant import Haskus.Utils.Functor import Haskus.Utils.Types.List import Haskus.Utils.Types import Haskus.Utils.ContFlow -import Unsafe.Coerce-import Data.Bifunctor-import GHC.Exts (Any,Constraint)---- | Recursive Functor-like Variant-newtype VariantF (xs :: [* -> *]) e-   = VariantF (V (ApplyAll e xs))---- | Apply its first argument to every element of the 2nd arg list------ > ApplyAll e '[f,g,h] ==> '[f e, g e, h e]----type family ApplyAll e (xs :: [* -> *]) :: [*] where-   ApplyAll e '[]       = '[]-   ApplyAll e (f ': fs) = f e ': ApplyAll e fs--instance (Show (V (ApplyAll e xs))) => Show (VariantF xs e) where-   show (VariantF x) = show x-deriving instance (Eq (V (ApplyAll e xs))) => Eq (VariantF xs e)-deriving instance (Ord (V (ApplyAll e xs))) => Ord (VariantF xs e)--instance Functor (VariantF '[]) where-   fmap _ = undefined--instance (Functor (VariantF fs), Functor f) => Functor (VariantF (f ': fs)) where-   fmap f (VariantF v) = case popVariantHead v of-      Right x -> toVariantFHead (fmap f x)-      Left xs -> toVariantFTail (fmap f (VariantF xs))---- | Pattern-match in a VariantF-pattern FV :: forall c cs e. c :< (ApplyAll e cs) => c -> VariantF cs e-pattern FV x = VariantF (V x)---- | Retrieve a single value-variantFToValue :: VariantF '[f] e -> f e-variantFToValue (VariantF v) = variantToValue v--appendVariantF :: forall (ys :: [* -> *]) (xs :: [* -> *]) e.-   ( ApplyAll e (Concat xs ys) ~ Concat (ApplyAll e xs) (ApplyAll e ys)-   ) => VariantF xs e -> VariantF (Concat xs ys) e-appendVariantF (VariantF v) = VariantF (appendVariant @(ApplyAll e ys) v)---- | Set the first value-toVariantFHead :: forall x xs e. x e -> VariantF (x ': xs) e-{-# INLINE toVariantFHead #-}-toVariantFHead v = VariantF (toVariantHead @(x e) @(ApplyAll e xs) v)---- | Set the tail-toVariantFTail :: forall x xs e. VariantF xs e -> VariantF (x ': xs) e-{-# INLINE toVariantFTail #-}-toVariantFTail (VariantF v) = VariantF (toVariantTail @(x e) @(ApplyAll e xs) v)---- | Pop VariantF head-popVariantFHead :: forall x xs e. VariantF (x ': xs) e -> Either (VariantF xs e) (x e)-{-# INLINE popVariantFHead #-}-popVariantFHead (VariantF v) = case popVariantHead v of-   Right x -> Right x-   Left xs -> Left (VariantF xs)---- | Pop VariantF-popVariantF :: forall x xs ys e.-   ( x e :< ApplyAll e xs-   , Filter (x e) (ApplyAll e xs) ~ ApplyAll e ys-   ) => VariantF xs e -> Either (VariantF ys e) (x e)-{-# INLINE popVariantF #-}-popVariantF (VariantF v) = case popVariant v of-   Right x -> Right x-   Left xs -> Left (VariantF xs)---- | Map the matching types of a variant-mapVariantF :: forall a b cs e ds as.-   ( MapVariant (a e) (b e) as-   , ds ~ ReplaceNS (IndexesOf a cs) b cs-   , as ~ ApplyAll e cs-   , ApplyAll e ds ~ ReplaceNS (IndexesOf (a e) as) (b e) as-   ) => (a e -> b e) -> VariantF cs e -> VariantF ds e-mapVariantF f (VariantF v) = VariantF (mapVariant @(a e) @(b e) @as f v)---- | xs is liftable in ys-type LiftableF e xs ys =-   ( IsSubset xs ys ~ 'True-   , LiftVariant (ApplyAll e xs) (ApplyAll e ys)-   )---- | Lift a VariantF into another-liftVariantF :: forall e as bs.-   ( LiftableF e as bs-   ) => VariantF as e -> VariantF bs e-liftVariantF (VariantF v) = VariantF (liftVariant' v)--class AlterVariantF (c :: (* -> *) -> Constraint) e (xs :: [* -> *]) where-   alterVariantF' :: (forall (f :: * -> *). c f => f e -> f e) -> Word -> Any -> Any--instance AlterVariantF c e '[] where-   {-# INLINE alterVariantF' #-}-   alterVariantF' _ = undefined--instance-   ( AlterVariantF c e xs-   , c x-   ) => AlterVariantF c e (x ': xs)-   where-      {-# INLINE alterVariantF' #-}-      alterVariantF' f t v =-         case t of-            0 -> unsafeCoerce (f (unsafeCoerce v :: x e))-            n -> alterVariantF' @c @e @xs f (n-1) v---- | Alter a variant. You need to specify the constraints required by the--- modifying function.------ Usage:------ >   alterVariantF @NoConstraint id         v--- >   alterVariantF @Resizable    (resize 4) v--- >--- >   -- Multiple constraints:--- >   class (Ord a, Num a) => OrdNum a--- >   instance (Ord a, Num a) => OrdNum a--- >   alterVariantF @OrdNum foo v----alterVariantF :: forall c e (xs :: [* -> *]).-   ( AlterVariantF c e xs-   ) => (forall (f :: * -> *). c f => f e -> f e) -> VariantF xs e -> VariantF xs e-{-# INLINABLE alterVariantF #-}-alterVariantF f (VariantF (Variant t a)) =-   VariantF (Variant t (alterVariantF' @c @e @xs f t a))---class AlgVariantF (c :: (* -> *) -> Constraint) e (xs :: [* -> *]) where-   algVariantF' :: (forall (f :: * -> *). c f => f e -> e) -> Word -> Any -> e--instance AlgVariantF c e '[] where-   {-# INLINE algVariantF' #-}-   algVariantF' _ = undefined--instance-   ( AlgVariantF c e xs-   , c x-   ) => AlgVariantF c e (x ': xs)-   where-      {-# INLINE algVariantF' #-}-      algVariantF' f t v =-         case t of-            0 -> f (unsafeCoerce v :: x e)-            n -> algVariantF' @c @e @xs f (n-1) v---- | Apply an algebra to a VariantF. You need to specify the constraints--- required by the modifying function.------ Usage:------ >  algVariantF @NoConstraint id         v--- >  algVariantF @Resizable    (resize 4) v----algVariantF :: forall c e (xs :: [* -> *]).-   ( AlgVariantF c e xs-   ) => (forall (f :: * -> *). c f => f e -> e) -> VariantF xs e -> e-{-# INLINABLE algVariantF #-}-algVariantF f (VariantF (Variant t a)) = algVariantF' @c @e @xs f t a----- | Split a VariantF in two-splitVariantF :: forall as xs e.-   ( Complement (ApplyAll e xs) (ApplyAll e as) ~ ApplyAll e (Complement xs as)-   , SplitVariant (ApplyAll e as) (ApplyAll e xs) (ApplyAll e xs)-   ) => VariantF xs e-     -> Either (VariantF as e) (VariantF (Complement xs as) e)-splitVariantF (VariantF v) = bimap VariantF VariantF (splitVariant v)---- | Convert a VariantF into a multi-continuation-variantFToCont :: ContVariant (ApplyAll e xs)-   => VariantF xs e -> ContFlow (ApplyAll e xs) r-variantFToCont (VariantF v) = variantToCont v---- | Convert a VariantF into a multi-continuation-variantFToContM ::-   ( ContVariant (ApplyAll e xs)-   , Monad m-   ) => m (VariantF xs e) -> ContFlow (ApplyAll e xs) (m r)-variantFToContM f = variantToContM (unvariantF <$> f)-   where-      unvariantF (VariantF v) = v---- | Convert a multi-continuation into a VariantF-contToVariantF :: forall xs e.-   ( ContVariant (ApplyAll e xs)-   ) => ContFlow (ApplyAll e xs) (V (ApplyAll e xs)) -> VariantF xs e-contToVariantF c = VariantF (contToVariant c)---- | Convert a multi-continuation into a VariantF-contToVariantFM :: forall xs e m.-   ( ContVariant (ApplyAll e xs)-   , Monad m-   ) => ContFlow (ApplyAll e xs) (m (V (ApplyAll e xs))) -> m (VariantF xs e)-contToVariantFM f = VariantF <$> contToVariantM f--instance ContVariant (ApplyAll e xs) => MultiCont (VariantF xs e) where-   type MultiContTypes (VariantF xs e) = ApplyAll e xs-   toCont = variantFToCont-   toContM = variantFToContM------------------------------------------------- Extensible ADT---------------------------------------------+import GHC.Exts (Constraint)  -- | An extensible ADT type EADT xs = Fix (VariantF xs)@@ -288,6 +61,7 @@    , Index (IndexOf (f e) (ApplyAll e cs)) (ApplyAll e cs) ~ f e    , PopVariant (f e) (ApplyAll e cs)    , KnownNat (IndexOf (f e) (ApplyAll e cs))+   , Remove (f e) (ApplyAll e cs) ~ ApplyAll e (Remove f cs)    )  -- | Pattern-match in an extensible ADT@@ -310,7 +84,7 @@ -- | Lift an EADT into another liftEADT :: forall e as bs.    ( e ~ Fix (VariantF bs)-   , LiftableF e as bs+   , LiftVariantF e as bs    , Functor (VariantF as)    ) => EADT as -> EADT bs liftEADT = cata (Fix . liftVariantF)@@ -320,8 +94,7 @@    ( f :<: xs    , e ~ EADT xs    , f e :< ApplyAll e xs-   , Filter (f e) (ApplyAll e xs) ~ ApplyAll e (Filter f xs)-   ) => EADT xs -> Either (VariantF (Filter f xs) (EADT xs)) (f (EADT xs))+   ) => EADT xs -> Either (VariantF (Remove f xs) (EADT xs)) (f (EADT xs)) popEADT (Fix v) = popVariantF v  type AlterEADT c xs = AlterVariantF c (EADT xs) xs
src/lib/Haskus/Utils/Variant.hs view
@@ -42,7 +42,7 @@    -- * Operations by type    , toVariant    , Member-   , Filter+   , Remove    , popVariant    , popVariantMaybe    , fromVariant@@ -69,7 +69,7 @@    -- * Conversions between variants    , appendVariant    , prependVariant-   , Liftable+   , LiftVariant    , liftVariant    , nubVariant    , productVariant@@ -97,7 +97,7 @@    , fromVariant'    , popVariant'    , toVariant'-   , LiftVariant+   , LiftVariant'    , PopVariant    ) where@@ -312,7 +312,7 @@  class PopVariant a xs where    -- | Remove a type from a variant-   popVariant' :: V xs -> Either (V (Filter a xs)) a+   popVariant' :: V xs -> Either (V (Remove a xs)) a  instance PopVariant a '[] where    {-# INLINE popVariant' #-}@@ -322,7 +322,7 @@       ( PopVariant a xs'       , n ~ MaybeIndexOf a xs       , xs' ~ RemoveAt1 n xs-      , Filter a xs' ~ Filter a xs+      , Remove a xs' ~ Remove a xs       , KnownNat n       , xs ~ (y ': ys)       ) => PopVariant a (y ': ys)@@ -385,7 +385,7 @@ -- remaining variant popVariant :: forall a xs.    ( a :< xs-   ) => V xs -> Either (V (Filter a xs)) a+   ) => V xs -> Either (V (Remove a xs)) a {-# INLINABLE popVariant #-} popVariant v = popVariant' @a v @@ -393,7 +393,7 @@ -- remaining variant popVariantMaybe :: forall a xs.    ( a :<? xs-   ) => V xs -> Either (V (Filter a xs)) a+   ) => V xs -> Either (V (Remove a xs)) a {-# INLINABLE popVariantMaybe #-} popVariantMaybe v = popVariant' @a v @@ -489,7 +489,7 @@    ( MapVariant a b cs    , ds ~ ReplaceNS (IndexesOf a cs) b cs    , rs ~ Nub ds-   , Liftable ds rs+   , LiftVariant ds rs    ) => (a -> b) -> V cs -> V rs {-# INLINABLE mapNubVariant #-} mapNubVariant f = nubVariant . mapVariant f@@ -561,7 +561,7 @@ foldMapVariant :: forall a cs ds i.    ( i ~ IndexOf a cs    , a :< cs-   ) => (a -> V ds) -> V cs -> V (InsertAt i (Filter a cs) ds)+   ) => (a -> V ds) -> V cs -> V (InsertAt i (Remove a cs) ds) foldMapVariant f v = case popVariant v of    Right a -> case f a of       Variant t x -> Variant (i + t) x@@ -717,22 +717,22 @@       n = natValue' @(Length ys)  -- | xs is liftable in ys-type Liftable xs ys =+type LiftVariant xs ys =    ( IsSubset xs ys ~ 'True-   , LiftVariant xs ys+   , LiftVariant' xs ys    ) -class LiftVariant xs ys where+class LiftVariant' xs ys where    liftVariant' :: V xs -> V ys -instance LiftVariant '[] ys where+instance LiftVariant' '[] ys where    {-# INLINE liftVariant' #-}    liftVariant' _ = undefined  instance forall xs ys x.-      ( LiftVariant xs ys+      ( LiftVariant' xs ys       , KnownNat (IndexOf x ys)-      ) => LiftVariant (x ': xs) ys+      ) => LiftVariant' (x ': xs) ys    where       {-# INLINE liftVariant' #-}       liftVariant' (Variant t a)@@ -744,13 +744,13 @@ -- -- Set values to the first matching type liftVariant :: forall ys xs.-   ( Liftable xs ys+   ( LiftVariant xs ys    ) => V xs -> V ys {-# INLINABLE liftVariant #-} liftVariant = liftVariant'  -- | Nub the type list-nubVariant :: (Liftable xs (Nub xs)) => V xs -> V (Nub xs)+nubVariant :: (LiftVariant xs (Nub xs)) => V xs -> V (Nub xs) {-# INLINABLE nubVariant #-} nubVariant = liftVariant 
src/lib/Haskus/Utils/Variant/Flow.hs view
@@ -25,7 +25,7 @@    , flowFor    , flowTraverseFilter    , flowForFilter-   , Liftable+   , LiftVariant    , (:<)    , (:<?)    -- * Functor, applicative equivalents@@ -225,7 +225,7 @@ flowSingle = flowSetN @0  -- | Lift a flow into another-flowLift :: (Liftable xs ys , Monad m) => Flow m xs -> Flow m ys+flowLift :: (LiftVariant xs ys , Monad m) => Flow m xs -> Flow m ys {-# INLINABLE flowLift #-} flowLift = fmap liftVariant @@ -296,8 +296,8 @@  -- | Bind two flows in a monadish way (error types union) flowBind :: forall xs ys zs m x.-   ( Liftable xs zs-   , Liftable ys zs+   ( LiftVariant xs zs+   , LiftVariant ys zs    , zs ~ Union xs ys    , Monad m    ) => Flow m (x ': ys) -> (x -> Flow m xs) -> Flow m zs@@ -313,7 +313,7 @@ flowMatch :: forall x xs zs m.    ( Monad m    , x :< xs-   , Liftable (Filter x xs) zs+   , LiftVariant (Remove x xs) zs    ) => Flow m xs -> (x -> Flow m zs) -> Flow m zs {-# INLINABLE flowMatch #-} flowMatch = (>%~^>)@@ -322,7 +322,7 @@ flowMatchFail :: forall x xs m.    ( Monad m    , x :< xs-   ) => Flow m xs -> (x -> m ()) -> Flow m (Filter x xs)+   ) => Flow m xs -> (x -> m ()) -> Flow m (Remove x xs) {-# INLINABLE flowMatchFail #-} flowMatchFail = (>%~!!>) @@ -373,8 +373,8 @@ -- | Extract the first value, lift both (.~^^>) :: forall m a xs ys zs.    ( Monad m-   , Liftable xs zs-   , Liftable ys zs+   , LiftVariant xs zs+   , LiftVariant ys zs    ) => V (a ': ys) -> (a -> Flow m xs) -> Flow m zs {-# INLINABLE (.~^^>) #-} (.~^^>) v f = makeFlowOp selectFirst (applyF f) combineLiftBoth v@@ -385,8 +385,8 @@ -- | Extract the first value, lift both (>.~^^>) :: forall m a xs ys zs.    ( Monad m-   , Liftable xs zs-   , Liftable ys zs+   , LiftVariant xs zs+   , LiftVariant ys zs    ) => Flow m (a ': ys) -> (a -> Flow m xs) -> Flow m zs {-# INLINABLE (>.~^^>) #-} (>.~^^>) = liftm (.~^^>)@@ -396,7 +396,7 @@ -- | Extract the first value, lift unselected (.~^>) :: forall m a ys zs.    ( Monad m-   , Liftable ys zs+   , LiftVariant ys zs    ) => V (a ': ys) -> (a -> Flow m zs) -> Flow m zs {-# INLINABLE (.~^>) #-} (.~^>) v f = makeFlowOp selectFirst (applyF f) combineLiftUnselected v@@ -406,7 +406,7 @@ -- | Extract the first value, lift unselected (>.~^>) :: forall m a ys zs.    ( Monad m-   , Liftable ys zs+   , LiftVariant ys zs    ) => Flow m (a ': ys) -> (a -> Flow m zs) -> Flow m zs {-# INLINABLE (>.~^>) #-} (>.~^>) = liftm (.~^>)@@ -433,8 +433,8 @@  -- | Take the first output, union the result (.~|>) ::-   ( Liftable xs zs-   , Liftable ys zs+   ( LiftVariant xs zs+   , LiftVariant ys zs    , zs ~ Union xs ys    , Monad m    ) => V (a ': ys) -> (a -> Flow m xs) -> Flow m zs@@ -445,8 +445,8 @@  -- | Take the first output, fusion the result (>.~|>) ::-   ( Liftable xs zs-   , Liftable ys zs+   ( LiftVariant xs zs+   , LiftVariant ys zs    , zs ~ Union xs ys    , Monad m    ) => Flow m (a ': ys) -> (a -> Flow m xs) -> Flow m zs@@ -580,8 +580,8 @@ -- | Applicative <*> equivalent, with error union (<|<) :: forall m xs ys zs y z.    ( Monad m-   , Liftable xs zs-   , Liftable ys zs+   , LiftVariant xs zs+   , LiftVariant ys zs    , zs ~ Union xs ys    ) => Flow m ((y -> z) ': xs) -> Flow m (y ': ys) -> Flow m (z ': zs) {-# INLINABLE (<|<) #-}@@ -640,8 +640,8 @@ -- | Extract the first value, lift the result (.~~^^>) :: forall m a xs ys zs.    ( Monad m-   , Liftable xs zs-   , Liftable ys zs+   , LiftVariant xs zs+   , LiftVariant ys zs    ) => V (a ': ys) -> Flow m xs -> Flow m zs {-# INLINABLE (.~~^^>) #-} (.~~^^>) v f = v .~^^> const f@@ -652,8 +652,8 @@ -- | Extract the first value, lift the result (>.~~^^>) :: forall m a xs ys zs.    ( Monad m-   , Liftable xs zs-   , Liftable ys zs+   , LiftVariant xs zs+   , LiftVariant ys zs    ) => Flow m (a ': ys) -> Flow m xs -> Flow m zs {-# INLINABLE (>.~~^^>) #-} (>.~~^^>) = liftm (.~~^^>)@@ -663,7 +663,7 @@ -- | Extract the first value, connect to the expected output (.~~^>) :: forall m a ys zs.    ( Monad m-   , Liftable ys zs+   , LiftVariant ys zs    ) => V (a ': ys) -> Flow m zs -> Flow m zs {-# INLINABLE (.~~^>) #-} (.~~^>) v f = v .~^> const f@@ -673,7 +673,7 @@ -- | Extract the first value, connect to the expected output (>.~~^>) :: forall m a ys zs.    ( Monad m-   , Liftable ys zs+   , LiftVariant ys zs    ) => Flow m (a ': ys) -> Flow m zs -> Flow m zs {-# INLINABLE (>.~~^>) #-} (>.~~^>) = liftm (.~~^>)@@ -700,8 +700,8 @@  -- | Take the first output, fusion the result (.~~|>) ::-   ( Liftable xs zs-   , Liftable ys zs+   ( LiftVariant xs zs+   , LiftVariant ys zs    , zs ~ Union xs ys    , Monad m    ) => V (a ': ys) -> Flow m xs -> Flow m zs@@ -712,8 +712,8 @@  -- | Take the first output, fusion the result (>.~~|>) ::-   ( Liftable xs zs-   , Liftable ys zs+   ( LiftVariant xs zs+   , LiftVariant ys zs    , zs ~ Union xs ys    , Monad m    ) => Flow m (a ': ys) -> Flow m xs -> Flow m zs@@ -844,7 +844,7 @@ -- | Extract the tail, lift the result (..~^^>) ::    ( Monad m-   , Liftable xs (a ': zs)+   , LiftVariant xs (a ': zs)    ) => V (a ': l) -> (V l -> Flow m xs) -> Flow m (a ': zs) {-# INLINABLE (..~^^>) #-} (..~^^>) v f = case popVariantHead v of@@ -856,7 +856,7 @@ -- | Extract the tail, lift the result (>..~^^>) ::    ( Monad m-   , Liftable xs (a ': zs)+   , LiftVariant xs (a ': zs)    ) => Flow m  (a ': l) -> (V l -> Flow m xs) -> Flow m (a ': zs) {-# INLINABLE (>..~^^>) #-} (>..~^^>) = liftm (..~^^>)@@ -889,7 +889,7 @@ (..?~^>) ::    ( Monad m    , a :<? xs-   , Liftable (Filter a xs) ys+   , LiftVariant (Remove a xs) ys    ) => V (x ': xs) -> (a -> Flow m ys) -> Flow m (x ': ys) {-# INLINABLE (..?~^>) #-} (..?~^>) v f = v ..~..> (\v' -> v' ?~^> f)@@ -900,7 +900,7 @@ (>..?~^>) ::    ( Monad m    , a :<? xs-   , Liftable (Filter a xs) ys+   , LiftVariant (Remove a xs) ys    ) => Flow m (x ': xs) -> (a -> Flow m ys) -> Flow m (x ': ys) {-# INLINABLE (>..?~^>) #-} (>..?~^>) = liftm (..?~^>)@@ -911,7 +911,7 @@ (..%~^>) ::    ( Monad m    , a :< xs-   , Liftable (Filter a xs) ys+   , LiftVariant (Remove a xs) ys    ) => V (x ': xs) -> (a -> Flow m ys) -> Flow m (x ': ys) {-# INLINABLE (..%~^>) #-} (..%~^>) v f = v ..~..> (\v' -> v' %~^> f)@@ -922,7 +922,7 @@ (>..%~^>) ::    ( Monad m    , a :< xs-   , Liftable (Filter a xs) ys+   , LiftVariant (Remove a xs) ys    ) => Flow m (x ': xs) -> (a -> Flow m ys) -> Flow m (x ': ys) {-# INLINABLE (>..%~^>) #-} (>..%~^>) = liftm (..%~^>)@@ -933,8 +933,8 @@ (..?~^^>) ::    ( Monad m    , a :<? xs-   , Liftable (Filter a xs) zs-   , Liftable ys zs+   , LiftVariant (Remove a xs) zs+   , LiftVariant ys zs    ) => V (x ': xs) -> (a -> Flow m ys) -> Flow m (x ': zs) {-# INLINABLE (..?~^^>) #-} (..?~^^>) v f = v ..~..> (\v' -> v' ?~^^> f)@@ -945,8 +945,8 @@ (>..?~^^>) ::    ( Monad m    , a :<? xs-   , Liftable (Filter a xs) zs-   , Liftable ys zs+   , LiftVariant (Remove a xs) zs+   , LiftVariant ys zs    ) => Flow m (x ': xs) -> (a -> Flow m ys) -> Flow m (x ': zs) {-# INLINABLE (>..?~^^>) #-} (>..?~^^>) = liftm (..?~^^>)@@ -957,8 +957,8 @@ (..%~^^>) ::    ( Monad m    , a :< xs-   , Liftable (Filter a xs) zs-   , Liftable ys zs+   , LiftVariant (Remove a xs) zs+   , LiftVariant ys zs    ) => V (x ': xs) -> (a -> Flow m ys) -> Flow m (x ': zs) {-# INLINABLE (..%~^^>) #-} (..%~^^>) v f = v ..~..> (\v' -> v' %~^^> f)@@ -969,8 +969,8 @@ (>..%~^^>) ::    ( Monad m    , a :< xs-   , Liftable (Filter a xs) zs-   , Liftable ys zs+   , LiftVariant (Remove a xs) zs+   , LiftVariant ys zs    ) => Flow m (x ': xs) -> (a -> Flow m ys) -> Flow m (x ': zs) {-# INLINABLE (>..%~^^>) #-} (>..%~^^>) = liftm (..%~^^>)@@ -981,7 +981,7 @@ (..?~$>) ::    ( Monad m    , a :<? xs-   , Liftable (Filter a xs) (x ': xs)+   , LiftVariant (Remove a xs) (x ': xs)    ) => V (x ': xs) -> (a -> Flow m (x ': xs)) -> Flow m (x ': xs) {-# INLINABLE (..?~$>) #-} (..?~$>) v f = case popVariantHead v of@@ -994,7 +994,7 @@ (>..?~$>) ::    ( Monad m    , a :<? xs-   , Liftable (Filter a xs) (x ': xs)+   , LiftVariant (Remove a xs) (x ': xs)    ) => Flow m (x ': xs) -> (a -> Flow m (x ': xs)) -> Flow m (x ': xs) {-# INLINABLE (>..?~$>) #-} (>..?~$>) = liftm (..?~$>)@@ -1005,7 +1005,7 @@ (..%~$>) ::    ( Monad m    , a :< xs-   , Liftable (Filter a xs) (x ': xs)+   , LiftVariant (Remove a xs) (x ': xs)    ) => V (x ': xs) -> (a -> Flow m (x ': xs)) -> Flow m (x ': xs) {-# INLINABLE (..%~$>) #-} (..%~$>) v f = case popVariantHead v of@@ -1018,7 +1018,7 @@ (>..%~$>) ::    ( Monad m    , a :< xs-   , Liftable (Filter a xs) (x ': xs)+   , LiftVariant (Remove a xs) (x ': xs)    ) => Flow m (x ': xs) -> (a -> Flow m (x ': xs)) -> Flow m (x ': xs) {-# INLINABLE (>..%~$>) #-} (>..%~$>) = liftm (..%~$>)@@ -1090,7 +1090,7 @@ (..?~!!>) ::    ( Monad m    , y :<? xs-   ) => V (x ': xs) -> (y -> m ()) -> Flow m (x ': Filter y xs)+   ) => V (x ': xs) -> (y -> m ()) -> Flow m (x ': Remove y xs) {-# INLINABLE (..?~!!>) #-} (..?~!!>) v f = v ..~..> (\xs -> xs ?~!!> f) @@ -1100,7 +1100,7 @@ (>..?~!!>) ::    ( Monad m    , y :<? xs-   ) => Flow m (x ': xs) -> (y -> m ()) -> Flow m (x ': Filter y xs)+   ) => Flow m (x ': xs) -> (y -> m ()) -> Flow m (x ': Remove y xs) {-# INLINABLE (>..?~!!>) #-} (>..?~!!>) = liftm (..?~!!>) @@ -1110,7 +1110,7 @@ (..%~!!>) ::    ( Monad m    , y :< xs-   ) => V (x ': xs) -> (y -> m ()) -> Flow m (x ': Filter y xs)+   ) => V (x ': xs) -> (y -> m ()) -> Flow m (x ': Remove y xs) {-# INLINABLE (..%~!!>) #-} (..%~!!>) v f = v ..~..> (\xs -> xs %~!!> f) @@ -1120,7 +1120,7 @@ (>..%~!!>) ::    ( Monad m    , y :< xs-   ) => Flow m (x ': xs) -> (y -> m ()) -> Flow m (x ': Filter y xs)+   ) => Flow m (x ': xs) -> (y -> m ()) -> Flow m (x ': Remove y xs) {-# INLINABLE (>..%~!!>) #-} (>..%~!!>) = liftm (..%~!!>) @@ -1176,7 +1176,7 @@  -- | Pop element, set the first value (?~.>) :: forall x xs y ys m.-   ( ys ~ Filter x xs+   ( ys ~ Remove x xs    , Monad m    , x :<? xs    ) => V xs -> (x -> m y) -> Flow m (y ': ys)@@ -1189,7 +1189,7 @@  -- | Pop element, set the first value (>?~.>) ::-   ( ys ~ Filter x xs+   ( ys ~ Remove x xs    , Monad m    , x :<? xs    ) => Flow m xs -> (x -> m y) -> Flow m (y ': ys)@@ -1200,7 +1200,7 @@  -- | Pop element, set the first value (%~.>) :: forall x xs y ys m.-   ( ys ~ Filter x xs+   ( ys ~ Remove x xs    , Monad m    , x :< xs    ) => V xs -> (x -> m y) -> Flow m (y ': ys)@@ -1211,7 +1211,7 @@  -- | Pop element, set the first value (>%~.>) ::-   ( ys ~ Filter x xs+   ( ys ~ Remove x xs    , Monad m    , x :< xs    ) => Flow m xs -> (x -> m y) -> Flow m (y ': ys)@@ -1225,10 +1225,10 @@    ( Monad m    , x :<? xs    , KnownNat (Length ys)-   ) => V xs -> (x -> Flow m ys) -> Flow m (Concat ys (Filter x xs))+   ) => V xs -> (x -> Flow m ys) -> Flow m (Concat ys (Remove x xs)) {-# INLINABLE (?~+>) #-} (?~+>) v f = case popVariantMaybe v of-   Right x -> appendVariant  @(Filter x xs) <$> f x+   Right x -> appendVariant  @(Remove x xs) <$> f x    Left ys -> prependVariant @ys            <$> return ys  infixl 0 ?~+>@@ -1238,7 +1238,7 @@    ( Monad m    , x :< xs    , KnownNat (Length ys)-   ) => Flow m xs -> (x -> Flow m ys) -> Flow m (Concat ys (Filter x xs))+   ) => Flow m xs -> (x -> Flow m ys) -> Flow m (Concat ys (Remove x xs)) {-# INLINABLE (>?~+>) #-} (>?~+>) = liftm (?~+>) @@ -1249,7 +1249,7 @@    ( Monad m    , x :< xs    , KnownNat (Length ys)-   ) => V xs -> (x -> Flow m ys) -> Flow m (Concat ys (Filter x xs))+   ) => V xs -> (x -> Flow m ys) -> Flow m (Concat ys (Remove x xs)) {-# INLINABLE (%~+>) #-} (%~+>) = (?~+>) @@ -1260,7 +1260,7 @@    ( Monad m    , x :< xs    , KnownNat (Length ys)-   ) => Flow m xs -> (x -> Flow m ys) -> Flow m (Concat ys (Filter x xs))+   ) => Flow m xs -> (x -> Flow m ys) -> Flow m (Concat ys (Remove x xs)) {-# INLINABLE (>%~+>) #-} (>%~+>) = liftm (%~+>) @@ -1270,8 +1270,8 @@ (?~^^>) :: forall x xs ys zs m.    ( Monad m    , x :<? xs-   , Liftable (Filter x xs) zs-   , Liftable ys zs+   , LiftVariant (Remove x xs) zs+   , LiftVariant ys zs    ) => V xs -> (x -> Flow m ys) -> Flow m zs {-# INLINABLE (?~^^>) #-} (?~^^>) v f = case popVariantMaybe v of@@ -1284,8 +1284,8 @@ (>?~^^>) :: forall x xs ys zs m.    ( Monad m    , x :<? xs-   , Liftable (Filter x xs) zs-   , Liftable ys zs+   , LiftVariant (Remove x xs) zs+   , LiftVariant ys zs    ) => Flow m xs -> (x -> Flow m ys) -> Flow m zs {-# INLINABLE (>?~^^>) #-} (>?~^^>) = liftm (?~^^>)@@ -1296,8 +1296,8 @@ (%~^^>) :: forall x xs ys zs m.    ( Monad m    , x :< xs-   , Liftable (Filter x xs) zs-   , Liftable ys zs+   , LiftVariant (Remove x xs) zs+   , LiftVariant ys zs    ) => V xs -> (x -> Flow m ys) -> Flow m zs {-# INLINABLE (%~^^>) #-} (%~^^>) = (?~^^>)@@ -1308,8 +1308,8 @@ (>%~^^>) :: forall x xs ys zs m.    ( Monad m    , x :< xs-   , Liftable (Filter x xs) zs-   , Liftable ys zs+   , LiftVariant (Remove x xs) zs+   , LiftVariant ys zs    ) => Flow m xs -> (x -> Flow m ys) -> Flow m zs {-# INLINABLE (>%~^^>) #-} (>%~^^>) = liftm (%~^^>)@@ -1320,7 +1320,7 @@ (?~^>) :: forall x xs zs m.    ( Monad m    , x :<? xs-   , Liftable (Filter x xs) zs+   , LiftVariant (Remove x xs) zs    ) => V xs -> (x -> Flow m zs) -> Flow m zs {-# INLINABLE (?~^>) #-} (?~^>) v f = case popVariantMaybe v of@@ -1333,7 +1333,7 @@ (>?~^>) :: forall x xs zs m.    ( Monad m    , x :<? xs-   , Liftable (Filter x xs) zs+   , LiftVariant (Remove x xs) zs    ) => Flow m xs -> (x -> Flow m zs) -> Flow m zs {-# INLINABLE (>?~^>) #-} (>?~^>) = liftm (?~^>)@@ -1344,7 +1344,7 @@ (%~^>) :: forall x xs zs m.    ( Monad m    , x :< xs-   , Liftable (Filter x xs) zs+   , LiftVariant (Remove x xs) zs    ) => V xs -> (x -> Flow m zs) -> Flow m zs {-# INLINABLE (%~^>) #-} (%~^>) = (?~^>)@@ -1355,7 +1355,7 @@ (>%~^>) :: forall x xs zs m.    ( Monad m    , x :< xs-   , Liftable (Filter x xs) zs+   , LiftVariant (Remove x xs) zs    ) => Flow m xs -> (x -> Flow m zs) -> Flow m zs {-# INLINABLE (>%~^>) #-} (>%~^>) = liftm (%~^>)@@ -1408,9 +1408,9 @@ (?~|>) :: forall x xs ys zs m.    ( Monad m    , x :<? xs-   , Liftable (Filter x xs) zs-   , Liftable ys zs-   , zs ~ Union (Filter x xs) ys+   , LiftVariant (Remove x xs) zs+   , LiftVariant ys zs+   , zs ~ Union (Remove x xs) ys    ) => V xs -> (x -> Flow m ys) -> Flow m zs {-# INLINABLE (?~|>) #-} (?~|>) v f = case popVariantMaybe v of@@ -1423,9 +1423,9 @@ (>?~|>) :: forall x xs ys zs m.    ( Monad m    , x :<? xs-   , Liftable (Filter x xs) zs-   , Liftable ys zs-   , zs ~ Union (Filter x xs) ys+   , LiftVariant (Remove x xs) zs+   , LiftVariant ys zs+   , zs ~ Union (Remove x xs) ys    ) => Flow m xs -> (x -> Flow m ys) -> Flow m zs {-# INLINABLE (>?~|>) #-} (>?~|>) = liftm (?~|>)@@ -1436,9 +1436,9 @@ (%~|>) :: forall x xs ys zs m.    ( Monad m    , x :< xs-   , Liftable (Filter x xs) zs-   , Liftable ys zs-   , zs ~ Union (Filter x xs) ys+   , LiftVariant (Remove x xs) zs+   , LiftVariant ys zs+   , zs ~ Union (Remove x xs) ys    ) => V xs -> (x -> Flow m ys) -> Flow m zs {-# INLINABLE (%~|>) #-} (%~|>) = (?~|>)@@ -1449,9 +1449,9 @@ (>%~|>) :: forall x xs ys zs m.    ( Monad m    , x :< xs-   , Liftable (Filter x xs) zs-   , Liftable ys zs-   , zs ~ Union (Filter x xs) ys+   , LiftVariant (Remove x xs) zs+   , LiftVariant ys zs+   , zs ~ Union (Remove x xs) ys    ) => Flow m xs -> (x -> Flow m ys) -> Flow m zs {-# INLINABLE (>%~|>) #-} (>%~|>) = liftm (%~|>)@@ -1546,7 +1546,7 @@ (?~!!>) :: forall x xs m.    ( Monad m    , x :<? xs-   ) => V xs -> (x -> m ()) -> Flow m (Filter x xs)+   ) => V xs -> (x -> m ()) -> Flow m (Remove x xs) {-# INLINABLE (?~!!>) #-} (?~!!>) v f = case popVariantMaybe v of    Right x -> f x >> error "?~!!> error"@@ -1558,7 +1558,7 @@ (>?~!!>) :: forall x xs m.    ( Monad m    , x :<? xs-   ) => Flow m xs -> (x -> m ()) -> Flow m (Filter x xs)+   ) => Flow m xs -> (x -> m ()) -> Flow m (Remove x xs) {-# INLINABLE (>?~!!>) #-} (>?~!!>) = liftm (?~!!>) @@ -1568,7 +1568,7 @@ (%~!!>) :: forall x xs m.    ( Monad m    , x :< xs-   ) => V xs -> (x -> m ()) -> Flow m (Filter x xs)+   ) => V xs -> (x -> m ()) -> Flow m (Remove x xs) {-# INLINABLE (%~!!>) #-} (%~!!>) = (?~!!>) @@ -1578,7 +1578,7 @@ (>%~!!>) :: forall x xs m.    ( Monad m    , x :< xs-   ) => Flow m xs -> (x -> m ()) -> Flow m (Filter x xs)+   ) => Flow m xs -> (x -> m ()) -> Flow m (Remove x xs) {-# INLINABLE (>%~!!>) #-} (>%~!!>) = liftm (%~!!>) @@ -1624,7 +1624,7 @@ -- | Select by type selectType ::    ( x :< xs-   ) => V xs -> Either (V (Filter x xs)) (V '[x])+   ) => V xs -> Either (V (Remove x xs)) (V '[x]) {-# INLINABLE selectType #-} selectType = fmap (toVariantAt @0) . popVariant @@ -1686,8 +1686,8 @@  -- | Union combineUnion ::-   ( Liftable xs (Union xs ys)-   , Liftable ys (Union xs ys)+   ( LiftVariant xs (Union xs ys)+   , LiftVariant ys (Union xs ys)    ) => Either (V ys) (V xs) -> V (Union xs ys) {-# INLINABLE combineUnion #-} combineUnion = \case@@ -1696,7 +1696,7 @@  -- | Lift unselected combineLiftUnselected ::-   ( Liftable ys xs+   ( LiftVariant ys xs    ) => Either (V ys) (V xs) -> V xs {-# INLINABLE combineLiftUnselected #-} combineLiftUnselected = \case@@ -1705,8 +1705,8 @@  -- | Lift both combineLiftBoth ::-   ( Liftable ys zs-   , Liftable xs zs+   ( LiftVariant ys zs+   , LiftVariant xs zs    ) => Either (V ys) (V xs) -> V zs {-# INLINABLE combineLiftBoth #-} combineLiftBoth = \case@@ -1907,7 +1907,7 @@    , ContVariant xs    , ys ~ FlattenVariant zs    , Flattenable (V zs) (V ys)-   , Liftable ys (Nub ys)+   , LiftVariant ys (Nub ys)    , rs ~ Nub ys    ) => V xs -> fs -> V rs (~||) v fs = nubVariant (flattenVariant (v -|| fs))@@ -1960,7 +1960,7 @@    , ys ~ FlattenVariant ks    , Flattenable (V ks) (V ys)    , rs ~ Nub ys-   , Liftable ys rs+   , LiftVariant ys rs    , Applicative m    , JoinVariant m zs    ) => V xs -> fs -> Flow m rs@@ -1976,7 +1976,7 @@    , ys ~ FlattenVariant ks    , Flattenable (V ks) (V ys)    , rs ~ Nub ys-   , Liftable ys rs+   , LiftVariant ys rs    , Monad m    , JoinVariant m zs    ) => Flow m xs -> fs -> Flow m rs
+ src/lib/Haskus/Utils/VariantF.hs view
@@ -0,0 +1,264 @@+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE AllowAmbiguousTypes #-}++-- | VariantF functor+module Haskus.Utils.VariantF+   ( VariantF (..)+   , ApplyAll+   , pattern FV+   , appendVariantF+   , toVariantFHead+   , toVariantFTail+   , popVariantFHead+   , variantFToValue+   , MapVariantF+   , mapVariantF+   , PopVariantF+   , popVariantF+   , LiftVariantF+   , liftVariantF+   , AlterVariantF+   , alterVariantF+   , AlgVariantF+   , algVariantF+   , SplitVariantF+   , splitVariantF+   , variantFToCont+   , variantFToContM+   , contToVariantF+   , contToVariantFM+   -- * Reexport+   , NoConstraint+   , module Haskus.Utils.Functor+   )+where++import Haskus.Utils.Variant+import Haskus.Utils.Functor+import Haskus.Utils.Types.List+import Haskus.Utils.ContFlow++import Unsafe.Coerce+import Data.Bifunctor+import GHC.Exts (Any,Constraint)++-- | Recursive Functor-like Variant+newtype VariantF (xs :: [* -> *]) e+   = VariantF (V (ApplyAll e xs))++-- | Apply its first argument to every element of the 2nd arg list+--+-- > ApplyAll e '[f,g,h] ==> '[f e, g e, h e]+--+type family ApplyAll e (xs :: [* -> *]) :: [*] where+   ApplyAll e '[]       = '[]+   ApplyAll e (f ': fs) = f e ': ApplyAll e fs++instance (Show (V (ApplyAll e xs))) => Show (VariantF xs e) where+   show (VariantF x) = show x+deriving instance (Eq (V (ApplyAll e xs))) => Eq (VariantF xs e)+deriving instance (Ord (V (ApplyAll e xs))) => Ord (VariantF xs e)++instance Functor (VariantF '[]) where+   fmap _ = undefined++instance (Functor (VariantF fs), Functor f) => Functor (VariantF (f ': fs)) where+   fmap f (VariantF v) = case popVariantHead v of+      Right x -> toVariantFHead (fmap f x)+      Left xs -> toVariantFTail (fmap f (VariantF xs))++-- | Pattern-match in a VariantF+pattern FV :: forall c cs e. c :< (ApplyAll e cs) => c -> VariantF cs e+pattern FV x = VariantF (V x)++-- | Retrieve a single value+variantFToValue :: VariantF '[f] e -> f e+variantFToValue (VariantF v) = variantToValue v++appendVariantF :: forall (ys :: [* -> *]) (xs :: [* -> *]) e.+   ( ApplyAll e (Concat xs ys) ~ Concat (ApplyAll e xs) (ApplyAll e ys)+   ) => VariantF xs e -> VariantF (Concat xs ys) e+appendVariantF (VariantF v) = VariantF (appendVariant @(ApplyAll e ys) v)++-- | Set the first value+toVariantFHead :: forall x xs e. x e -> VariantF (x ': xs) e+{-# INLINE toVariantFHead #-}+toVariantFHead v = VariantF (toVariantHead @(x e) @(ApplyAll e xs) v)++-- | Set the tail+toVariantFTail :: forall x xs e. VariantF xs e -> VariantF (x ': xs) e+{-# INLINE toVariantFTail #-}+toVariantFTail (VariantF v) = VariantF (toVariantTail @(x e) @(ApplyAll e xs) v)++-- | Pop VariantF head+popVariantFHead :: forall x xs e. VariantF (x ': xs) e -> Either (VariantF xs e) (x e)+{-# INLINE popVariantFHead #-}+popVariantFHead (VariantF v) = case popVariantHead v of+   Right x -> Right x+   Left xs -> Left (VariantF xs)++type PopVariantF x xs e =+   ( x e :< ApplyAll e xs+   , Remove (x e) (ApplyAll e xs) ~ ApplyAll e (Remove x xs)+   )++-- | Pop VariantF+popVariantF :: forall x xs e.+   ( PopVariantF x xs e+   ) => VariantF xs e -> Either (VariantF (Remove x xs) e) (x e)+{-# INLINE popVariantF #-}+popVariantF (VariantF v) = case popVariant v of+   Right x -> Right x+   Left xs -> Left (VariantF xs)++type MapVariantF a b cs ds e =+   ( MapVariant (a e) (b e) (ApplyAll e cs)+   , ds ~ ReplaceNS (IndexesOf a cs) b cs+   , ApplyAll e ds ~ ReplaceNS (IndexesOf (a e) (ApplyAll e cs)) (b e) (ApplyAll e cs)+   )++-- | Map the matching types of a variant+mapVariantF :: forall a b cs ds e.+   ( MapVariantF a b cs ds e+   ) => (a e -> b e) -> VariantF cs e -> VariantF ds e+mapVariantF f (VariantF v) = VariantF (mapVariant @(a e) @(b e) @(ApplyAll e cs) f v)++-- | xs is liftable in ys+type LiftVariantF e xs ys =+   ( IsSubset xs ys ~ 'True+   , LiftVariant (ApplyAll e xs) (ApplyAll e ys)+   )++-- | Lift a VariantF into another+liftVariantF :: forall e as bs.+   ( LiftVariantF e as bs+   ) => VariantF as e -> VariantF bs e+liftVariantF (VariantF v) = VariantF (liftVariant' v)++class AlterVariantF (c :: (* -> *) -> Constraint) e (xs :: [* -> *]) where+   alterVariantF' :: (forall (f :: * -> *). c f => f e -> f e) -> Word -> Any -> Any++instance AlterVariantF c e '[] where+   {-# INLINE alterVariantF' #-}+   alterVariantF' _ = undefined++instance+   ( AlterVariantF c e xs+   , c x+   ) => AlterVariantF c e (x ': xs)+   where+      {-# INLINE alterVariantF' #-}+      alterVariantF' f t v =+         case t of+            0 -> unsafeCoerce (f (unsafeCoerce v :: x e))+            n -> alterVariantF' @c @e @xs f (n-1) v++-- | Alter a variant. You need to specify the constraints required by the+-- modifying function.+--+-- Usage:+--+-- >   alterVariantF @NoConstraint id         v+-- >   alterVariantF @Resizable    (resize 4) v+-- >+-- >   -- Multiple constraints:+-- >   class (Ord a, Num a) => OrdNum a+-- >   instance (Ord a, Num a) => OrdNum a+-- >   alterVariantF @OrdNum foo v+--+alterVariantF :: forall c e (xs :: [* -> *]).+   ( AlterVariantF c e xs+   ) => (forall (f :: * -> *). c f => f e -> f e) -> VariantF xs e -> VariantF xs e+{-# INLINABLE alterVariantF #-}+alterVariantF f (VariantF (Variant t a)) =+   VariantF (Variant t (alterVariantF' @c @e @xs f t a))+++class AlgVariantF (c :: (* -> *) -> Constraint) e (xs :: [* -> *]) where+   algVariantF' :: (forall (f :: * -> *). c f => f e -> e) -> Word -> Any -> e++instance AlgVariantF c e '[] where+   {-# INLINE algVariantF' #-}+   algVariantF' _ = undefined++instance+   ( AlgVariantF c e xs+   , c x+   ) => AlgVariantF c e (x ': xs)+   where+      {-# INLINE algVariantF' #-}+      algVariantF' f t v =+         case t of+            0 -> f (unsafeCoerce v :: x e)+            n -> algVariantF' @c @e @xs f (n-1) v++-- | Apply an algebra to a VariantF. You need to specify the constraints+-- required by the modifying function.+--+-- Usage:+--+-- >  algVariantF @NoConstraint id         v+-- >  algVariantF @Resizable    (resize 4) v+--+algVariantF :: forall c e (xs :: [* -> *]).+   ( AlgVariantF c e xs+   ) => (forall (f :: * -> *). c f => f e -> e) -> VariantF xs e -> e+{-# INLINABLE algVariantF #-}+algVariantF f (VariantF (Variant t a)) = algVariantF' @c @e @xs f t a++type SplitVariantF as xs e =+   ( Complement (ApplyAll e xs) (ApplyAll e as) ~ ApplyAll e (Complement xs as)+   , SplitVariant (ApplyAll e as) (ApplyAll e xs) (ApplyAll e xs)+   )++-- | Split a VariantF in two+splitVariantF :: forall as xs e.+   ( SplitVariantF as xs e+   ) => VariantF xs e+     -> Either (VariantF as e) (VariantF (Complement xs as) e)+splitVariantF (VariantF v) = bimap VariantF VariantF (splitVariant v)++-- | Convert a VariantF into a multi-continuation+variantFToCont :: ContVariant (ApplyAll e xs)+   => VariantF xs e -> ContFlow (ApplyAll e xs) r+variantFToCont (VariantF v) = variantToCont v++-- | Convert a VariantF into a multi-continuation+variantFToContM ::+   ( ContVariant (ApplyAll e xs)+   , Monad m+   ) => m (VariantF xs e) -> ContFlow (ApplyAll e xs) (m r)+variantFToContM f = variantToContM (unvariantF <$> f)+   where+      unvariantF (VariantF v) = v++-- | Convert a multi-continuation into a VariantF+contToVariantF :: forall xs e.+   ( ContVariant (ApplyAll e xs)+   ) => ContFlow (ApplyAll e xs) (V (ApplyAll e xs)) -> VariantF xs e+contToVariantF c = VariantF (contToVariant c)++-- | Convert a multi-continuation into a VariantF+contToVariantFM :: forall xs e m.+   ( ContVariant (ApplyAll e xs)+   , Monad m+   ) => ContFlow (ApplyAll e xs) (m (V (ApplyAll e xs))) -> m (VariantF xs e)+contToVariantFM f = VariantF <$> contToVariantM f++instance ContVariant (ApplyAll e xs) => MultiCont (VariantF xs e) where+   type MultiContTypes (VariantF xs e) = ApplyAll e xs+   toCont = variantFToCont+   toContM = variantFToContM