data-effects-core 0.2.0.0 → 0.4.0.0
raw patch · 14 files changed
+1717/−328 lines, 14 filesdep +freedep +hspecdep +kan-extensionsdep −compdatadep −tasty-hunitdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: free, hspec, kan-extensions, primitive, tasty-hspec, unliftio
Dependencies removed: compdata, tasty-hunit
Dependency ranges changed: base
API changes (from Hackage documentation)
- Control.Effect: class SendFOE (ins :: EffectF) (f :: Type -> Type)
- Control.Effect: class SendHOE (sig :: EffectH) (f :: Type -> Type)
- Control.Effect: instance Control.Effect.SendFOE ins f => Control.Effect.SendHOE (Data.Effect.LiftFOE ins) f
- Control.Effect: sendFOE :: SendFOE ins f => ins a -> f a
- Control.Effect: sendHOE :: SendHOE sig f => sig f a -> f a
- Control.Effect.Key: ByKey :: f a -> ByKey (key :: k) (f :: Type -> Type) a
- Control.Effect.Key: [runByKey] :: ByKey (key :: k) (f :: Type -> Type) a -> f a
- Control.Effect.Key: class SendFOEBy (key :: k) (ins :: EffectF) (f :: Type -> Type) | key f -> ins
- Control.Effect.Key: class SendHOEBy (key :: k) (sig :: EffectH) (f :: Type -> Type) | key f -> sig
- Control.Effect.Key: instance forall e k (key :: k) (f :: * -> *). Control.Monad.Error.Class.MonadError e f => Control.Monad.Error.Class.MonadError e (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall k (key :: k) (f :: * -> *). Control.Monad.Fail.MonadFail f => Control.Monad.Fail.MonadFail (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall k (key :: k) (f :: * -> *). Control.Monad.Fix.MonadFix f => Control.Monad.Fix.MonadFix (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall k (key :: k) (f :: * -> *). Control.Monad.IO.Class.MonadIO f => Control.Monad.IO.Class.MonadIO (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall k (key :: k) (f :: * -> *). GHC.Base.Alternative f => GHC.Base.Alternative (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall k (key :: k) (f :: * -> *). GHC.Base.Applicative f => GHC.Base.Applicative (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall k (key :: k) (f :: * -> *). GHC.Base.Functor f => GHC.Base.Functor (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall k (key :: k) (f :: * -> *). GHC.Base.Monad f => GHC.Base.Monad (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall k (key :: k) (f :: * -> *). GHC.Base.MonadPlus f => GHC.Base.MonadPlus (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall k (key :: k) (ins :: Data.Effect.EffectF) (f :: * -> *). Control.Effect.Key.SendFOEBy key ins f => Control.Effect.SendFOE ins (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall k (key :: k) (sig :: Data.Effect.EffectH) (f :: * -> *). (Control.Effect.Key.SendHOEBy key sig f, Data.Comp.Multi.HFunctor.HFunctor sig) => Control.Effect.SendHOE sig (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall r k (key :: k) (f :: * -> *). Control.Monad.Reader.Class.MonadReader r f => Control.Monad.Reader.Class.MonadReader r (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall r w s k (key :: k) (f :: * -> *). (Control.Monad.Reader.Class.MonadReader r f, Control.Monad.Writer.Class.MonadWriter w f, Control.Monad.State.Class.MonadState s f) => Control.Monad.RWS.Class.MonadRWS r w s (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall s k (key :: k) (f :: * -> *). Control.Monad.State.Class.MonadState s f => Control.Monad.State.Class.MonadState s (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: instance forall w k (key :: k) (f :: * -> *). Control.Monad.Writer.Class.MonadWriter w f => Control.Monad.Writer.Class.MonadWriter w (Control.Effect.Key.ByKey key f)
- Control.Effect.Key: key :: forall {k} (key :: k) f a. ByKey key f a -> f a
- Control.Effect.Key: newtype ByKey (key :: k) (f :: Type -> Type) a
- Control.Effect.Key: sendFOEBy :: SendFOEBy key ins f => ins a -> f a
- Control.Effect.Key: sendHOEBy :: SendHOEBy key sig f => sig f a -> f a
- Control.Effect.Tag: ViaTag :: f a -> ViaTag (tag :: k) (f :: Type -> Type) a
- Control.Effect.Tag: [runViaTag] :: ViaTag (tag :: k) (f :: Type -> Type) a -> f a
- Control.Effect.Tag: instance forall e k (tag :: k) (f :: * -> *). Control.Monad.Error.Class.MonadError e f => Control.Monad.Error.Class.MonadError e (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k (ins :: Data.Effect.EffectF) (tag :: k) (f :: * -> *). Control.Effect.SendFOE (ins Data.Effect.Tag.# tag) f => Control.Effect.SendFOE ins (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k (sig :: Data.Effect.EffectH) (tag :: k) (f :: * -> *). (Control.Effect.SendHOE (sig Data.Effect.Tag.## tag) f, Data.Comp.Multi.HFunctor.HFunctor sig) => Control.Effect.SendHOE sig (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k (tag :: k) (f :: * -> *). Control.Monad.Fail.MonadFail f => Control.Monad.Fail.MonadFail (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k (tag :: k) (f :: * -> *). Control.Monad.Fix.MonadFix f => Control.Monad.Fix.MonadFix (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k (tag :: k) (f :: * -> *). Control.Monad.IO.Class.MonadIO f => Control.Monad.IO.Class.MonadIO (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k (tag :: k) (f :: * -> *). GHC.Base.Alternative f => GHC.Base.Alternative (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k (tag :: k) (f :: * -> *). GHC.Base.Applicative f => GHC.Base.Applicative (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k (tag :: k) (f :: * -> *). GHC.Base.Functor f => GHC.Base.Functor (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k (tag :: k) (f :: * -> *). GHC.Base.Monad f => GHC.Base.Monad (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k (tag :: k) (f :: * -> *). GHC.Base.MonadPlus f => GHC.Base.MonadPlus (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k1 k2 (key :: k1) (ins :: Data.Effect.EffectF) (tag :: k2) (f :: * -> *). Control.Effect.Key.SendFOEBy key (ins Data.Effect.Tag.# tag) f => Control.Effect.Key.SendFOEBy key ins (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall k1 k2 (key :: k1) (sig :: Data.Effect.EffectH) (tag :: k2) (f :: * -> *). (Control.Effect.Key.SendHOEBy key (sig Data.Effect.Tag.## tag) f, Data.Comp.Multi.HFunctor.HFunctor sig) => Control.Effect.Key.SendHOEBy key sig (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall r k (tag :: k) (f :: * -> *). Control.Monad.Reader.Class.MonadReader r f => Control.Monad.Reader.Class.MonadReader r (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall r w s k (tag :: k) (f :: * -> *). (Control.Monad.Reader.Class.MonadReader r f, Control.Monad.Writer.Class.MonadWriter w f, Control.Monad.State.Class.MonadState s f) => Control.Monad.RWS.Class.MonadRWS r w s (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall s k (tag :: k) (f :: * -> *). Control.Monad.State.Class.MonadState s f => Control.Monad.State.Class.MonadState s (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: instance forall w k (tag :: k) (f :: * -> *). Control.Monad.Writer.Class.MonadWriter w f => Control.Monad.Writer.Class.MonadWriter w (Control.Effect.Tag.ViaTag tag f)
- Control.Effect.Tag: newtype ViaTag (tag :: k) (f :: Type -> Type) a
- Control.Effect.Tag: tag :: forall {k} (tag :: k) f a. ViaTag tag f a -> f a
- Data.Effect: LiftFOE :: ins a -> LiftFOE (ins :: EffectF) (f :: Type -> Type) a
- Data.Effect: [unliftFOE] :: LiftFOE (ins :: EffectF) (f :: Type -> Type) a -> ins a
- Data.Effect: instance Data.Comp.Multi.HFunctor.HFunctor (Data.Effect.LiftFOE ins)
- Data.Effect: instance Data.Foldable.Foldable ins => Data.Foldable.Foldable (Data.Effect.LiftFOE ins f)
- Data.Effect: instance Data.Traversable.Traversable ins => Data.Traversable.Traversable (Data.Effect.LiftFOE ins f)
- Data.Effect: instance GHC.Base.Functor ins => GHC.Base.Functor (Data.Effect.LiftFOE ins f)
- Data.Effect: newtype LiftFOE (ins :: EffectF) (f :: Type -> Type) a
- Data.Effect: type EffectF = Type -> Type
- Data.Effect: type EffectH = Type -> Type -> Type -> Type
- Data.Effect: type LNop = LiftFOE Nop
- Data.Effect.HFunctor: (:&:) :: f g e -> a -> (:&:) (f :: (Type -> Type) -> k -> Type) a (g :: Type -> Type) (e :: k)
- Data.Effect.HFunctor: Inl :: f h e -> (:+:) (f :: (Type -> Type) -> k -> Type) (g :: (Type -> Type) -> k -> Type) (h :: Type -> Type) (e :: k)
- Data.Effect.HFunctor: Inr :: g h e -> (:+:) (f :: (Type -> Type) -> k -> Type) (g :: (Type -> Type) -> k -> Type) (h :: Type -> Type) (e :: k)
- Data.Effect.HFunctor: caseH :: forall {k} f (a :: Type -> Type) (b :: k) c g. (f a b -> c) -> (g a b -> c) -> (f :+: g) a b -> c
- Data.Effect.HFunctor: class DistAnn (s :: Type -> Type -> Type -> Type) p (s' :: Type -> Type -> Type -> Type) | s' -> s, s' -> p
- Data.Effect.HFunctor: class RemA (s :: Type -> Type -> Type -> Type) (s' :: Type -> Type -> Type -> Type) | s -> s'
- Data.Effect.HFunctor: class Subsume (e :: Emb) (f :: Type -> Type -> Type -> Type) (g :: Type -> Type -> Type -> Type)
- Data.Effect.HFunctor: data ( (f :: Type -> Type -> k -> Type) :+: (g :: Type -> Type -> k -> Type) ) (h :: Type -> Type) (e :: k)
- Data.Effect.HFunctor: infixl 5 :<:
- Data.Effect.HFunctor: infixr 6 :+:
- Data.Effect.HFunctor: infixr 7 :&:
- Data.Effect.HFunctor: inj :: forall (f :: (Type -> Type) -> Type -> Type) (g :: (Type -> Type) -> Type -> Type) (a :: Type -> Type). f :<: g => f a :-> g a
- Data.Effect.HFunctor: inj' :: forall (a :: Type -> Type). Subsume e f g => Proxy e -> f a :-> g a
- Data.Effect.HFunctor: injectA :: forall (a :: Type -> Type). DistAnn s p s' => p -> s a :-> s' a
- Data.Effect.HFunctor: prj' :: forall (a :: Type -> Type). Subsume e f g => Proxy e -> NatM Maybe (g a) (f a)
- Data.Effect.HFunctor: proj :: forall (f :: (Type -> Type) -> Type -> Type) (g :: (Type -> Type) -> Type -> Type) (a :: Type -> Type). f :<: g => NatM Maybe (g a) (f a)
- Data.Effect.HFunctor: projectA :: forall (a :: Type -> Type). DistAnn s p s' => s' a :-> (s a :&: p)
- Data.Effect.HFunctor: remA :: forall (a :: Type -> Type). RemA s s' => s a :-> s' a
- Data.Effect.HFunctor: spl :: forall (f :: (Type -> Type) -> Type -> Type) (f1 :: (Type -> Type) -> Type -> Type) (f2 :: (Type -> Type) -> Type -> Type) (a :: Type -> Type) (b :: Type -> Type). f :=: (f1 :+: f2) => (f1 a :-> b) -> (f2 a :-> b) -> f a :-> b
- Data.Effect.HFunctor: type (f :: Type -> Type -> Type -> Type) :<: (g :: Type -> Type -> Type -> Type) = Subsume ComprEmb Elem f g f g
- Data.Effect.HFunctor: type family Elem (f :: Type -> Type -> Type -> Type) (g :: Type -> Type -> Type -> Type) :: Emb
- Data.Effect.HFunctor.HCont: instance Data.Comp.Multi.HFunctor.HFunctor (Data.Effect.HFunctor.HCont.HCont ff g)
- Data.Effect.Key: Key :: ins a -> Key (key :: k) (ins :: EffectF) a
- Data.Effect.Key: KeyH :: sig f a -> KeyH (key :: k) (sig :: EffectH) (f :: Type -> Type) a
- Data.Effect.Key: [unKeyH] :: KeyH (key :: k) (sig :: EffectH) (f :: Type -> Type) a -> sig f a
- Data.Effect.Key: [unKey] :: Key (key :: k) (ins :: EffectF) a -> ins a
- Data.Effect.Key: infixr 7 ##>
- Data.Effect.Key: instance forall k (key :: k) (ins :: Data.Effect.EffectF). Data.Foldable.Foldable ins => Data.Foldable.Foldable (Data.Effect.Key.Key key ins)
- Data.Effect.Key: instance forall k (key :: k) (ins :: Data.Effect.EffectF). Data.Traversable.Traversable ins => Data.Traversable.Traversable (Data.Effect.Key.Key key ins)
- Data.Effect.Key: instance forall k (key :: k) (ins :: Data.Effect.EffectF). GHC.Base.Functor ins => GHC.Base.Functor (Data.Effect.Key.Key key ins)
- Data.Effect.Key: instance forall k (key :: k) (sig :: Data.Effect.EffectH) (f :: * -> *). Data.Foldable.Foldable (sig f) => Data.Foldable.Foldable (Data.Effect.Key.KeyH key sig f)
- Data.Effect.Key: instance forall k (key :: k) (sig :: Data.Effect.EffectH) (f :: * -> *). Data.Traversable.Traversable (sig f) => Data.Traversable.Traversable (Data.Effect.Key.KeyH key sig f)
- Data.Effect.Key: instance forall k (key :: k) (sig :: Data.Effect.EffectH) (f :: * -> *). GHC.Base.Functor (sig f) => GHC.Base.Functor (Data.Effect.Key.KeyH key sig f)
- Data.Effect.Key: instance forall k (key :: k) (sig :: Data.Effect.EffectH). Data.Comp.Multi.HFunctor.HFunctor sig => Data.Comp.Multi.HFunctor.HFunctor (Data.Effect.Key.KeyH key sig)
- Data.Effect.Key: newtype Key (key :: k) (ins :: EffectF) a
- Data.Effect.Key: newtype KeyH (key :: k) (sig :: EffectH) (f :: Type -> Type) a
- Data.Effect.Key: pattern K :: forall {k} key ins a. ins a -> Key key ins a
- Data.Effect.Key: pattern KH :: forall {k} key sig f a. sig f a -> KeyH key sig f a
- Data.Effect.Key: type (##>) = KeyH :: k -> EffectH -> Type -> Type -> Type -> Type
- Data.Effect.Tag: TagH :: sig f a -> TagH (sig :: EffectH) (tag :: k) (f :: Type -> Type) a
- Data.Effect.Tag: [unTagH] :: TagH (sig :: EffectH) (tag :: k) (f :: Type -> Type) a -> sig f a
- Data.Effect.Tag: infixl 8 ##
- Data.Effect.Tag: instance forall (ins :: Data.Effect.EffectF) k (tag :: k). Data.Foldable.Foldable ins => Data.Foldable.Foldable (Data.Effect.Tag.Tag ins tag)
- Data.Effect.Tag: instance forall (ins :: Data.Effect.EffectF) k (tag :: k). Data.Traversable.Traversable ins => Data.Traversable.Traversable (Data.Effect.Tag.Tag ins tag)
- Data.Effect.Tag: instance forall (ins :: Data.Effect.EffectF) k (tag :: k). GHC.Base.Functor ins => GHC.Base.Functor (Data.Effect.Tag.Tag ins tag)
- Data.Effect.Tag: instance forall (sig :: Data.Effect.EffectH) k (tag :: k) (f :: * -> *). Data.Foldable.Foldable (sig f) => Data.Foldable.Foldable (Data.Effect.Tag.TagH sig tag f)
- Data.Effect.Tag: instance forall (sig :: Data.Effect.EffectH) k (tag :: k) (f :: * -> *). Data.Traversable.Traversable (sig f) => Data.Traversable.Traversable (Data.Effect.Tag.TagH sig tag f)
- Data.Effect.Tag: instance forall (sig :: Data.Effect.EffectH) k (tag :: k) (f :: * -> *). GHC.Base.Functor (sig f) => GHC.Base.Functor (Data.Effect.Tag.TagH sig tag f)
- Data.Effect.Tag: instance forall (sig :: Data.Effect.EffectH) k (tag :: k). Data.Comp.Multi.HFunctor.HFunctor sig => Data.Comp.Multi.HFunctor.HFunctor (Data.Effect.Tag.TagH sig tag)
- Data.Effect.Tag: newtype Tag (ins :: EffectF) (tag :: k) a
- Data.Effect.Tag: newtype TagH (sig :: EffectH) (tag :: k) (f :: Type -> Type) a
- Data.Effect.Tag: pattern T :: forall {k} tag ins a. ins a -> Tag ins tag a
- Data.Effect.Tag: pattern TH :: forall {k} tag sig f a. sig f a -> TagH sig tag f a
- Data.Effect.Tag: type (##) = TagH :: EffectH -> k -> Type -> Type -> Type -> Type
+ Control.Effect: Eff :: ff (Union es (Eff ff es)) a -> Eff ff es a
+ Control.Effect: [unEff] :: Eff ff es a -> ff (Union es (Eff ff es)) a
+ Control.Effect: callCC_ :: forall ref a b es ff c. (CC ref :> es, Monad (Eff ff es), Free c ff) => ((a -> Eff ff es b) -> Eff ff es a) -> Eff ff es a
+ Control.Effect: class (forall f. c (ff f)) => Free c (ff :: (Type -> Type) -> Type -> Type) | ff -> c
+ Control.Effect: convertEff :: forall ff gg es a c c'. (Free c ff, Free c' gg, forall r. c (gg r)) => Eff ff es a -> Eff gg es a
+ Control.Effect: convertFree :: (Free c ff, Free c' gg, c (gg r)) => ff r a -> gg r a
+ Control.Effect: emb :: forall f es ff a c. (Emb f :> es, Free c ff) => f a -> Eff ff es a
+ Control.Effect: hoist :: (Free c ff, c (ff g)) => (forall x. f x -> g x) -> ff f a -> ff g a
+ Control.Effect: infixr 3 $
+ Control.Effect: infixr 4 $$
+ Control.Effect: instance (Data.Effect.CC ref Data.Effect.OpenUnion.:> es, GHC.Base.Monad (Control.Effect.Eff ff es), Control.Effect.Free c ff) => Control.Monad.Cont.Class.MonadCont (Control.Effect.Eff ff es)
+ Control.Effect: instance (Data.Effect.Emb GHC.Types.IO Data.Effect.OpenUnion.:> es, GHC.Base.Monad (Control.Effect.Eff ff es), Control.Effect.Free c ff) => Control.Monad.IO.Class.MonadIO (Control.Effect.Eff ff es)
+ Control.Effect: instance (Data.Effect.Empty Data.Effect.OpenUnion.:> es, Data.Effect.ChooseH Data.Effect.OpenUnion.:> es, GHC.Base.Applicative (Control.Effect.Eff ff es), Control.Effect.Free c ff) => GHC.Base.Alternative (Control.Effect.Eff ff es)
+ Control.Effect: instance (Data.Effect.Empty Data.Effect.OpenUnion.:> es, Data.Effect.ChooseH Data.Effect.OpenUnion.:> es, GHC.Base.Monad (Control.Effect.Eff ff es), Control.Effect.Free c ff) => GHC.Base.MonadPlus (Control.Effect.Eff ff es)
+ Control.Effect: instance (Data.Effect.Fail Data.Effect.OpenUnion.:> es, GHC.Base.Monad (Control.Effect.Eff ff es), Control.Effect.Free c ff) => Control.Monad.Fail.MonadFail (Control.Effect.Eff ff es)
+ Control.Effect: instance (Data.Effect.Fix Data.Effect.OpenUnion.:> es, GHC.Base.Monad (Control.Effect.Eff ff es), Control.Effect.Free c ff) => Control.Monad.Fix.MonadFix (Control.Effect.Eff ff es)
+ Control.Effect: instance (Data.Effect.OpenUnion.FindByLabel Data.Effect.AskLabel (Data.Effect.Ask r) es, Data.Effect.Local r Data.Effect.OpenUnion.:> es, Data.Effect.OpenUnion.FindByLabel Data.Effect.TellLabel (Data.Effect.Tell w) es, Data.Effect.WriterH w Data.Effect.OpenUnion.:> es, Data.Effect.OpenUnion.FindByLabel Data.Effect.StateLabel (Data.Effect.State s) es, GHC.Base.Monoid w, GHC.Base.Monad (Control.Effect.Eff ff es), Control.Effect.Free c ff) => Control.Monad.RWS.Class.MonadRWS r w s (Control.Effect.Eff ff es)
+ Control.Effect: instance (Data.Effect.OpenUnion.FindByLabel Data.Effect.AskLabel (Data.Effect.Ask r) es, Data.Effect.Local r Data.Effect.OpenUnion.:> es, GHC.Base.Monad (Control.Effect.Eff ff es), Control.Effect.Free c ff) => Control.Monad.Reader.Class.MonadReader r (Control.Effect.Eff ff es)
+ Control.Effect: instance (Data.Effect.OpenUnion.FindByLabel Data.Effect.StateLabel (Data.Effect.State s) es, GHC.Base.Monad (Control.Effect.Eff ff es), Control.Effect.Free c ff) => Control.Monad.State.Class.MonadState s (Control.Effect.Eff ff es)
+ Control.Effect: instance (Data.Effect.OpenUnion.FindByLabel Data.Effect.TellLabel (Data.Effect.Tell w) es, Data.Effect.WriterH w Data.Effect.OpenUnion.:> es, GHC.Base.Monoid w, GHC.Base.Monad (Control.Effect.Eff ff es), Control.Effect.Free c ff) => Control.Monad.Writer.Class.MonadWriter w (Control.Effect.Eff ff es)
+ Control.Effect: instance (Data.Effect.OpenUnion.FindByLabel Data.Effect.ThrowLabel (Data.Effect.Throw e) es, Data.Effect.Catch e Data.Effect.OpenUnion.:> es, GHC.Base.Monad (Control.Effect.Eff ff es), Control.Effect.Free c ff) => Control.Monad.Error.Class.MonadError e (Control.Effect.Eff ff es)
+ Control.Effect: instance (Data.Effect.UnliftIO Data.Effect.OpenUnion.:> es, Data.Effect.Emb GHC.Types.IO Data.Effect.OpenUnion.:> es, GHC.Base.Monad (Control.Effect.Eff ff es), Control.Effect.Free c ff) => Control.Monad.IO.Unlift.MonadUnliftIO (Control.Effect.Eff ff es)
+ Control.Effect: instance (forall (f :: * -> *). GHC.Base.Functor (ff f)) => GHC.Base.Functor (Control.Effect.Eff ff es)
+ Control.Effect: instance (forall (r :: * -> *). GHC.Base.Applicative (ff r)) => GHC.Base.Applicative (Control.Effect.Eff ff es)
+ Control.Effect: instance (forall (r :: * -> *). GHC.Base.Monad (ff r)) => GHC.Base.Monad (Control.Effect.Eff ff es)
+ Control.Effect: instance Control.Effect.Free GHC.Base.Alternative Control.Alternative.Free.Alt
+ Control.Effect: instance Control.Effect.Free GHC.Base.Alternative Control.Alternative.Free.Final.Alt
+ Control.Effect: instance Control.Effect.Free GHC.Base.Applicative Control.Applicative.Free.Ap
+ Control.Effect: instance Control.Effect.Free GHC.Base.Applicative Control.Applicative.Free.Fast.Ap
+ Control.Effect: instance Control.Effect.Free GHC.Base.Applicative Control.Applicative.Free.Final.Ap
+ Control.Effect: instance Control.Effect.Free GHC.Base.Functor Data.Functor.Coyoneda.Coyoneda
+ Control.Effect: liftFree :: Free c ff => f a -> ff f a
+ Control.Effect: newtype Eff ff es a
+ Control.Effect: pass :: forall w a es ff c. (Tell w :> es, WriterH w :> es, Monad (Eff ff es), Free c ff) => Eff ff es (w -> w, a) -> Eff ff es a
+ Control.Effect: perform :: forall e es ff a c. (e :> es, Free c ff) => e (Eff ff es) a -> Eff ff es a
+ Control.Effect: perform' :: forall key e es ff a c. (Has key e es, Free c ff) => e (Eff ff es) a -> Eff ff es a
+ Control.Effect: perform'' :: forall tag e es ff a c. ((e # tag) :> es, Free c ff) => e (Eff ff es) a -> Eff ff es a
+ Control.Effect: retract :: (Free c ff, c f) => ff f a -> f a
+ Control.Effect: runFree :: (Free c ff, c g) => (forall x. f x -> g x) -> ff f a -> g a
+ Control.Effect: send :: forall e es ff a c. (e `In` es, Free c ff) => e (Eff ff es) a -> Eff ff es a
+ Control.Effect: sendAt :: forall i es ff a c. (KnownIndex i es, Free c ff) => At i es (Eff ff es) a -> Eff ff es a
+ Control.Effect: sendFor :: forall e es ff a c. (KnownOrder e, Free c ff) => Membership e es -> e (Eff ff es) a -> Eff ff es a
+ Control.Effect: sub :: forall ref a b es ff c. (CC ref :> es, Monad (Eff ff es), Free c ff) => (ref a -> Eff ff es b) -> (a -> Eff ff es b) -> Eff ff es b
+ Control.Effect: type e ~~> f = e f ~> f
+ Control.Effect.Interpret: interpose :: forall e es ff a c. (e :> es, Free c ff) => (e ~~> Eff ff es) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Interpret: interposeFor :: forall e es ff a c. (KnownOrder e, Free c ff) => Membership e es -> (e ~~> Eff ff es) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Interpret: interposeIn :: forall e es ff a c. (e `In` es, Free c ff) => (e ~~> Eff ff es) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Interpret: interposeOn :: forall key e es ff a c. (Has key e es, Free c ff) => (e ~~> Eff ff es) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Interpret: interpret :: forall e es ff a c. (KnownOrder e, Free c ff) => (e ~~> Eff ff es) -> Eff ff (e ': es) a -> Eff ff es a
+ Control.Effect.Interpret: interpretAll :: forall es es' ff a c. Free c ff => (Union es ~~> Eff ff es') -> Eff ff es a -> Eff ff es' a
+ Control.Effect.Interpret: interprets :: forall es r ff a c. (KnownLength es, Free c ff) => (Union es ~~> Eff ff r) -> Eff ff (es ++ r) a -> Eff ff r a
+ Control.Effect.Interpret: iterAllEff :: forall es f ff a c. (Free c ff, c f) => (Union es ~~> f) -> Eff ff es a -> f a
+ Control.Effect.Interpret: preinterpose :: forall e es ff a c. (e :> es, Free c ff) => (e ~~> Eff ff es) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Interpret: preinterposeFor :: forall e es ff a c. (KnownOrder e, Free c ff) => Membership e es -> (e ~~> Eff ff es) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Interpret: preinterposeIn :: forall e es ff a c. (e `In` es, Free c ff) => (e ~~> Eff ff es) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Interpret: preinterposeOn :: forall key e es ff a c. (Has key e es, Free c ff) => (e ~~> Eff ff es) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Interpret: reinterpret :: forall e es es' ff a c. (Suffix es es', KnownOrder e, Free c ff) => (e ~~> Eff ff es') -> Eff ff (e ': es) a -> Eff ff es' a
+ Control.Effect.Interpret: reinterprets :: forall es r r' ff a c. (Suffix r r', KnownLength es, Free c ff) => (Union es (Eff ff r') ~> Eff ff r') -> Eff ff (es ++ r) a -> Eff ff r' a
+ Control.Effect.Interpret: runEff :: (Free c ff, c f) => Eff ff '[Emb f] a -> f a
+ Control.Effect.Interpret: runPure :: (Free c ff, c Identity) => Eff ff '[] a -> a
+ Control.Effect.Transform: onlyFOEs :: forall es a ff c. (Free c ff, WeakenHOEs es) => Eff ff (RemoveHOEs es) a -> Eff ff es a
+ Control.Effect.Transform: raise :: forall e es a ff c. Free c ff => Eff ff es a -> Eff ff (e ': es) a
+ Control.Effect.Transform: raisePrefix :: forall es' es a ff c. (KnownLength es', Free c ff) => Eff ff es a -> Eff ff (es' ++ es) a
+ Control.Effect.Transform: raisePrefix1 :: forall fs x es a ff c. (KnownLength fs, Free c ff) => Eff ff es a -> Eff ff (Each fs x ++ es) a
+ Control.Effect.Transform: raiseSuffix :: forall es' es a ff c. Free c ff => Eff ff es a -> Eff ff (es ++ es') a
+ Control.Effect.Transform: raiseUnder :: forall e0 e1 es a ff c. Free c ff => Eff ff (e0 ': es) a -> Eff ff (e0 ': (e1 ': es)) a
+ Control.Effect.Transform: raises :: forall es es' a ff c. (Suffix es es', Free c ff) => Eff ff es a -> Eff ff es' a
+ Control.Effect.Transform: raisesUnder :: forall e es es' a ff c. (Suffix es es', Free c ff) => Eff ff (e ': es) a -> Eff ff (e ': es') a
+ Control.Effect.Transform: raisesUnders :: forall es es' a ff c. (SuffixUnder es es', Free c ff) => Eff ff es a -> Eff ff es' a
+ Control.Effect.Transform: rewrite :: forall e es a ff c. (e :> es, Free c ff) => (e (Eff ff es) ~> e (Eff ff es)) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Transform: rewriteFor :: forall e es a ff c. (KnownOrder e, Free c ff) => Membership e es -> (e (Eff ff es) ~> e (Eff ff es)) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Transform: rewriteIn :: forall e es a ff c. (e `In` es, Free c ff) => (e (Eff ff es) ~> e (Eff ff es)) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Transform: rewriteOn :: forall key e es a ff c. (Has key e es, Free c ff) => (e (Eff ff es) ~> e (Eff ff es)) -> Eff ff es a -> Eff ff es a
+ Control.Effect.Transform: subsume :: forall e es a ff c. (e `In` es, Free c ff) => Eff ff (e ': es) a -> Eff ff es a
+ Control.Effect.Transform: subsumeUnder :: forall e1 e0 es a ff c. (e1 `In` es, KnownOrder e0, Free c ff) => Eff ff (e0 ': (e1 ': es)) a -> Eff ff (e0 ': es) a
+ Control.Effect.Transform: tag :: forall tag e es a ff c. (KnownOrder e, KnownOrder (e # tag), Free c ff) => Eff ff (e ': es) a -> Eff ff ((e # tag) ': es) a
+ Control.Effect.Transform: transAll :: forall es es' ff a c. Free c ff => (Union es (Eff ff es') ~> Union es' (Eff ff es')) -> Eff ff es a -> Eff ff es' a
+ Control.Effect.Transform: transform :: forall e e' es a ff c. (KnownOrder e, KnownOrder e', Free c ff) => (e (Eff ff (e' ': es)) ~> e' (Eff ff (e' ': es))) -> Eff ff (e ': es) a -> Eff ff (e' ': es) a
+ Control.Effect.Transform: translate :: forall e e' es a ff c. (KnownOrder e, e' :> es, Free c ff) => (e (Eff ff es) ~> e' (Eff ff es)) -> Eff ff (e ': es) a -> Eff ff es a
+ Control.Effect.Transform: translateFor :: forall e e' es a ff c. (KnownOrder e, KnownOrder e', Free c ff) => Membership e' es -> (e (Eff ff es) ~> e' (Eff ff es)) -> Eff ff (e ': es) a -> Eff ff es a
+ Control.Effect.Transform: translateIn :: forall e e' es a ff c. (KnownOrder e, e' `In` es, Free c ff) => (e (Eff ff es) ~> e' (Eff ff es)) -> Eff ff (e ': es) a -> Eff ff es a
+ Control.Effect.Transform: translateOn :: forall key e e' es a ff c. (KnownOrder e, Has key e' es, Free c ff) => (e (Eff ff es) ~> e' (Eff ff es)) -> Eff ff (e ': es) a -> Eff ff es a
+ Control.Effect.Transform: untag :: forall tag e es a ff c. (KnownOrder e, KnownOrder (e # tag), Free c ff) => Eff ff ((e # tag) ': es) a -> Eff ff (e ': es) a
+ Data.Effect: Emb :: e a -> Emb e (f :: Type -> Type) (a :: Type)
+ Data.Effect: FirstOrder :: EffectOrder
+ Data.Effect: HigherOrder :: EffectOrder
+ Data.Effect: Unemb :: (forall f. e f a) -> Unemb e a
+ Data.Effect: [Abort] :: ans -> Shift ans ref f a
+ Data.Effect: [Ask] :: Ask r f r
+ Data.Effect: [Call] :: ref a -> a -> Shift ans ref f ans
+ Data.Effect: [Catch] :: f a -> (e -> f a) -> Catch e f a
+ Data.Effect: [Censor] :: (w -> w) -> f a -> WriterH w f a
+ Data.Effect: [ChooseH] :: f a -> f a -> ChooseH f a
+ Data.Effect: [Choose] :: Choose f Bool
+ Data.Effect: [Efix] :: (a -> f a) -> Fix f a
+ Data.Effect: [Empty] :: Empty f a
+ Data.Effect: [Fail] :: String -> Fail f a
+ Data.Effect: [Get] :: State s f s
+ Data.Effect: [Jump] :: ref a -> a -> CC ref f b
+ Data.Effect: [Listen] :: f a -> WriterH w f (w, a)
+ Data.Effect: [Local] :: (r -> r) -> f a -> Local r f a
+ Data.Effect: [Put] :: s -> State s f ()
+ Data.Effect: [SubFork] :: CC ref f (Either (ref a) a)
+ Data.Effect: [SubShiftFork] :: Shift ans ref f (Either (ref a) a)
+ Data.Effect: [Tell] :: w -> Tell w f ()
+ Data.Effect: [Throw] :: e -> Throw e f a
+ Data.Effect: [WithRunInBase] :: ((forall x. f x -> b x) -> b a) -> UnliftBase b f a
+ Data.Effect: [getEmb] :: Emb e (f :: Type -> Type) (a :: Type) -> e a
+ Data.Effect: [getUnemb] :: Unemb e a -> forall f. e f a
+ Data.Effect: class (OrderOf e ~ 'FirstOrder, forall f g a. Coercible (e f a) (e g a)) => FirstOrder (e :: Effect)
+ Data.Effect: data Ask r :: Effect
+ Data.Effect: data AskLabel
+ Data.Effect: data CC ref :: Effect
+ Data.Effect: data CCLabel
+ Data.Effect: data Catch e :: Effect
+ Data.Effect: data CatchLabel
+ Data.Effect: data Choose :: Effect
+ Data.Effect: data ChooseH :: Effect
+ Data.Effect: data ChooseHLabel
+ Data.Effect: data ChooseLabel
+ Data.Effect: data EffectOrder
+ Data.Effect: data EmbLabel (e :: Type -> Type)
+ Data.Effect: data Empty :: Effect
+ Data.Effect: data EmptyLabel
+ Data.Effect: data Fail :: Effect
+ Data.Effect: data FailLabel
+ Data.Effect: data Fix :: Effect
+ Data.Effect: data FixLabel
+ Data.Effect: data Local r :: Effect
+ Data.Effect: data LocalLabel
+ Data.Effect: data NopLabel
+ Data.Effect: data Shift ans ref :: Effect
+ Data.Effect: data ShiftLabel
+ Data.Effect: data State s :: Effect
+ Data.Effect: data StateLabel
+ Data.Effect: data Tell w :: Effect
+ Data.Effect: data TellLabel
+ Data.Effect: data Throw e :: Effect
+ Data.Effect: data ThrowLabel
+ Data.Effect: data UnliftBase b f (a :: Type)
+ Data.Effect: data UnliftBaseLabel (b :: Type -> Type)
+ Data.Effect: data WriterH w :: Effect
+ Data.Effect: data WriterHLabel
+ Data.Effect: instance Data.Effect.FirstOrder (Data.Effect.Ask r)
+ Data.Effect: instance Data.Effect.FirstOrder (Data.Effect.CC ref)
+ Data.Effect: instance Data.Effect.FirstOrder (Data.Effect.Emb e)
+ Data.Effect: instance Data.Effect.FirstOrder (Data.Effect.Shift ans ref)
+ Data.Effect: instance Data.Effect.FirstOrder (Data.Effect.State s)
+ Data.Effect: instance Data.Effect.FirstOrder (Data.Effect.Tell w)
+ Data.Effect: instance Data.Effect.FirstOrder (Data.Effect.Throw e)
+ Data.Effect: instance Data.Effect.FirstOrder Data.Effect.Choose
+ Data.Effect: instance Data.Effect.FirstOrder Data.Effect.Empty
+ Data.Effect: instance Data.Effect.FirstOrder Data.Effect.Fail
+ Data.Effect: instance Data.Effect.FirstOrder Data.Effect.Nop
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor (Data.Effect.Ask r)
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor (Data.Effect.CC ref)
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor (Data.Effect.Catch w)
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor (Data.Effect.Emb e)
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor (Data.Effect.Local r)
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor (Data.Effect.Shift ans ref)
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor (Data.Effect.State s)
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor (Data.Effect.Tell w)
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor (Data.Effect.Throw e)
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor (Data.Effect.UnliftBase b)
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor (Data.Effect.WriterH w)
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor Data.Effect.Choose
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor Data.Effect.ChooseH
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor Data.Effect.Empty
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor Data.Effect.Fail
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor Data.Effect.Fix
+ Data.Effect: instance Data.Effect.HFunctor.HFunctor Data.Effect.Nop
+ Data.Effect: instance Data.Foldable.Foldable e => Data.Foldable.Foldable (Data.Effect.Emb e f)
+ Data.Effect: instance Data.Traversable.Traversable e => Data.Traversable.Traversable (Data.Effect.Emb e f)
+ Data.Effect: instance GHC.Base.Applicative e => GHC.Base.Applicative (Data.Effect.Emb e f)
+ Data.Effect: instance GHC.Base.Functor e => GHC.Base.Functor (Data.Effect.Emb e f)
+ Data.Effect: instance GHC.Base.Monad e => GHC.Base.Monad (Data.Effect.Emb e f)
+ Data.Effect: instance GHC.Classes.Eq Data.Effect.EffectOrder
+ Data.Effect: instance GHC.Classes.Ord Data.Effect.EffectOrder
+ Data.Effect: instance GHC.Show.Show Data.Effect.EffectOrder
+ Data.Effect: newtype Emb e (f :: Type -> Type) (a :: Type)
+ Data.Effect: newtype Unemb e a
+ Data.Effect: type Effect = (Type -> Type) -> Type -> Type
+ Data.Effect: type UnliftIO = UnliftBase IO
+ Data.Effect: type family LabelOf (e :: Effect)
+ Data.Effect.HFunctor.HCont: instance Data.Effect.HFunctor.HFunctor (Data.Effect.HFunctor.HCont.HCont ff g)
+ Data.Effect.OpenUnion: (!++) :: forall es es' f a r. KnownLength es => (Union es f a -> r) -> (Union es' f a -> r) -> Union (es ++ es') f a -> r
+ Data.Effect.OpenUnion: (!:) :: Elem e order => (e f a -> r) -> (Union es f a -> r) -> Union (e ': es) f a -> r
+ Data.Effect.OpenUnion: UnsafeMembership :: Int -> Membership (e :: Effect) (es :: [Effect])
+ Data.Effect.OpenUnion: [UnsafeFirst] :: Ordership 'FirstOrder e f g
+ Data.Effect.OpenUnion: [UnsafeHigher] :: (forall x. g x -> f x) -> Ordership 'HigherOrder e f g
+ Data.Effect.OpenUnion: [UnsafeUnion] :: {-# UNPACK #-} !Int -> e g a -> {-# UNPACK #-} !EffectOrder -> (forall x. g x -> f x) -> Union es f a
+ Data.Effect.OpenUnion: [unMembership] :: Membership (e :: Effect) (es :: [Effect]) -> Int
+ Data.Effect.OpenUnion: bundleUnion :: forall es es' f a. KnownLength es => Union (es ++ es') f a -> Union (Union es ': es') f a
+ Data.Effect.OpenUnion: caseAnyOrder :: HFunctor e => (e f a -> r) -> (Union es f a -> r) -> Union (e ': es) f a -> r
+ Data.Effect.OpenUnion: class (order ~ OrderOf e) => Elem e order
+ Data.Effect.OpenUnion: class (dscr ~ Discriminator resolver e, dscr' ~ Discriminator resolver (HeadOf r)) => ErrorIfNotFound resolver dscr dscr' (e :: Effect) (r :: [Effect]) (w :: [Effect])
+ Data.Effect.OpenUnion: class FOEs es
+ Data.Effect.OpenUnion: class (dscr ~ Discriminator resolver e, dscr' ~ Discriminator resolver (HeadOf r)) => FindBy resolver dscr dscr' e r | resolver dscr dscr' r -> e
+ Data.Effect.OpenUnion: class KnownLength xs
+ Data.Effect.OpenUnion: class Suffix (es :: [Effect]) (es' :: [Effect])
+ Data.Effect.OpenUnion: class SuffixUnder (es :: [Effect]) (es' :: [Effect])
+ Data.Effect.OpenUnion: class (orderOfHead ~ OrderOf (HeadOf es)) => WeakenHOEs_ es countF orderOfHead
+ Data.Effect.OpenUnion: coerceFOEs :: FOEs es => Union es f a -> Union es g a
+ Data.Effect.OpenUnion: compareMembership :: Membership e es -> Membership e' es -> Maybe (e :~: e')
+ Data.Effect.OpenUnion: continuationOfInterpretation :: Ordership 'HigherOrder e f g -> forall x. g x -> f x
+ Data.Effect.OpenUnion: data IdentityDiscriminator (e :: Effect)
+ Data.Effect.OpenUnion: data IdentityResolver
+ Data.Effect.OpenUnion: data KeyDiscriminator key
+ Data.Effect.OpenUnion: data KeyResolver
+ Data.Effect.OpenUnion: data LabelResolver
+ Data.Effect.OpenUnion: data NoKeyDiscriminator
+ Data.Effect.OpenUnion: data Ordership (o :: EffectOrder) (e :: Effect) (f :: Type -> Type) (g :: Type -> Type)
+ Data.Effect.OpenUnion: data Union (es :: [Effect]) (f :: Type -> Type) (a :: Type)
+ Data.Effect.OpenUnion: decomp :: (KnownOrder e, HFunctor e) => Union (e ': es) f a -> Either (e f a) (Union es f a)
+ Data.Effect.OpenUnion: extract :: Elem e order => Union '[e] f a -> e f a
+ Data.Effect.OpenUnion: extractAnyOrder :: HFunctor e => Union es f a -> e f a
+ Data.Effect.OpenUnion: findBy :: FindBy resolver dscr dscr' e r => Membership e r
+ Data.Effect.OpenUnion: firstOrdership :: FirstOrder e => Ordership 'FirstOrder e f g
+ Data.Effect.OpenUnion: foldHoeIndexShifter :: WeakenHOEs_ es countF orderOfHead => (Int -> Int) -> Int -> Int
+ Data.Effect.OpenUnion: hfmapDynUnsafeCoerce :: HFunctor e' => EffectOrder -> (forall x. f x -> g x) -> e f a -> e' g a
+ Data.Effect.OpenUnion: hfmapUnion :: (forall x. f x -> g x) -> Union es f a -> Union es g a
+ Data.Effect.OpenUnion: higherOrdership :: OrderOf e ~ 'HigherOrder => (forall x. g x -> f x) -> Ordership 'HigherOrder e f g
+ Data.Effect.OpenUnion: identityMembership :: forall e es. FindBy IdentityResolver (IdentityDiscriminator e) (IdentityDiscriminator (HeadOf es)) e es => Membership e es
+ Data.Effect.OpenUnion: infix 4 `In`
+ Data.Effect.OpenUnion: infixr 5 !++
+ Data.Effect.OpenUnion: inject :: Elem e order => Membership e es -> e f a -> Union es f a
+ Data.Effect.OpenUnion: instance ((TypeError ...), dscr GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver e, dscr' GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver (Data.Effect.OpenUnion.HeadOf '[])) => Data.Effect.OpenUnion.ErrorIfNotFound resolver dscr dscr' e '[] w
+ Data.Effect.OpenUnion: instance (Data.Effect.FirstOrder e, Data.Effect.OpenUnion.FOEs es) => Data.Effect.OpenUnion.FOEs (e : es)
+ Data.Effect.OpenUnion: instance (Data.Effect.FirstOrder e, Data.Effect.OpenUnion.WeakenHOEs_ es (countF GHC.TypeNats.+ 1) _orderOfHead) => Data.Effect.OpenUnion.WeakenHOEs_ (e : es) countF 'Data.Effect.FirstOrder
+ Data.Effect.OpenUnion: instance (Data.Effect.OrderOf e GHC.Types.~ 'Data.Effect.HigherOrder, Data.Effect.HFunctor.HFunctor e) => Data.Effect.OpenUnion.Elem e 'Data.Effect.HigherOrder
+ Data.Effect.OpenUnion: instance (Data.Effect.OrderOf e GHC.Types.~ 'Data.Effect.HigherOrder, Data.Effect.OpenUnion.WeakenHOEs_ es countF _orderOfHead, GHC.TypeNats.KnownNat countF) => Data.Effect.OpenUnion.WeakenHOEs_ (e : es) countF 'Data.Effect.HigherOrder
+ Data.Effect.OpenUnion: instance (dscr GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver e, dscr GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver e', e GHC.Types.~ e') => Data.Effect.OpenUnion.ErrorIfNotFound resolver dscr dscr e (e' : r) w
+ Data.Effect.OpenUnion: instance (dscr GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver e, dscr GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver e', e GHC.Types.~ e') => Data.Effect.OpenUnion.FindBy resolver dscr dscr e (e' : r)
+ Data.Effect.OpenUnion: instance (dscr GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver e, dscr' GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver (Data.Effect.OpenUnion.HeadOf r)) => Data.Effect.OpenUnion.ErrorIfNotFound resolver dscr dscr' e r w
+ Data.Effect.OpenUnion: instance (dscr GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver e, dscr' GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver e', Data.Effect.OpenUnion.ErrorIfNotFound resolver dscr (Data.Effect.OpenUnion.Discriminator resolver (Data.Effect.OpenUnion.HeadOf r)) e r w) => Data.Effect.OpenUnion.ErrorIfNotFound resolver dscr dscr' e (e' : r) w
+ Data.Effect.OpenUnion: instance (dscr GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver e, dscr' GHC.Types.~ Data.Effect.OpenUnion.Discriminator resolver e', Data.Effect.OpenUnion.FindBy resolver dscr (Data.Effect.OpenUnion.Discriminator resolver (Data.Effect.OpenUnion.HeadOf r)) e r) => Data.Effect.OpenUnion.FindBy resolver dscr dscr' e (e' : r)
+ Data.Effect.OpenUnion: instance Data.Effect.FirstOrder e => Data.Effect.OpenUnion.Elem e 'Data.Effect.FirstOrder
+ Data.Effect.OpenUnion: instance Data.Effect.HFunctor.HFunctor (Data.Effect.OpenUnion.Union es)
+ Data.Effect.OpenUnion: instance Data.Effect.OpenUnion.FOEs '[]
+ Data.Effect.OpenUnion: instance Data.Effect.OpenUnion.KnownLength '[]
+ Data.Effect.OpenUnion: instance Data.Effect.OpenUnion.Suffix es es
+ Data.Effect.OpenUnion: instance Data.Effect.OpenUnion.Suffix es es' => Data.Effect.OpenUnion.Suffix es (e : es')
+ Data.Effect.OpenUnion: instance Data.Effect.OpenUnion.Suffix es es' => Data.Effect.OpenUnion.SuffixUnder es es'
+ Data.Effect.OpenUnion: instance Data.Effect.OpenUnion.SuffixUnder es es' => Data.Effect.OpenUnion.SuffixUnder (e : es) (e : es')
+ Data.Effect.OpenUnion: instance GHC.Classes.Eq (Data.Effect.OpenUnion.Membership e es)
+ Data.Effect.OpenUnion: instance GHC.Show.Show (Data.Effect.OpenUnion.Membership e es)
+ Data.Effect.OpenUnion: instance forall k (orderOfHead :: Data.Effect.EffectOrder) (countF :: k). (Data.Effect.OrderOf (Data.Effect.OpenUnion.HeadOf '[]) GHC.Types.~ orderOfHead) => Data.Effect.OpenUnion.WeakenHOEs_ '[] countF orderOfHead
+ Data.Effect.OpenUnion: instance forall k (xs :: [k]) (x :: k). Data.Effect.OpenUnion.KnownLength xs => Data.Effect.OpenUnion.KnownLength (x : xs)
+ Data.Effect.OpenUnion: intVal :: forall n. KnownNat n => Int
+ Data.Effect.OpenUnion: keyMembership :: forall key e es. FindBy KeyResolver (KeyDiscriminator key) (KeyOf (HeadOf es)) (e # key) es => Membership (e # key) es
+ Data.Effect.OpenUnion: labelMembership :: forall e es. FindBy LabelResolver (LabelOf e) (LabelOf (HeadOf es)) e es => Membership e es
+ Data.Effect.OpenUnion: mapUnion :: forall es es' f a. (forall e. Membership e es -> Membership e es') -> Union es f a -> Union es' f a
+ Data.Effect.OpenUnion: membership :: forall resolver dscr e es. FindBy resolver dscr (Discriminator resolver (HeadOf es)) e es => Membership e es
+ Data.Effect.OpenUnion: membershipAt :: forall i es. KnownNat i => Membership (At i es) es
+ Data.Effect.OpenUnion: mergeUnion :: forall es es' f a. KnownLength es => Either (Union es f a) (Union es' f a) -> Union (es ++ es') f a
+ Data.Effect.OpenUnion: mkUnion :: Membership e es -> Ordership o e f g -> e g a -> Union es f a
+ Data.Effect.OpenUnion: newtype Membership (e :: Effect) (es :: [Effect])
+ Data.Effect.OpenUnion: nil :: Union '[] f a -> r
+ Data.Effect.OpenUnion: nilMembership :: Membership e '[] -> r
+ Data.Effect.OpenUnion: offset :: SuffixUnder es es' => Int
+ Data.Effect.OpenUnion: pattern Here :: Membership e (e ': es)
+ Data.Effect.OpenUnion: pattern There :: Membership e es -> Membership e (e ': es)
+ Data.Effect.OpenUnion: prefixFor :: forall es' es e. KnownLength es' => Membership e es -> Membership e (es' ++ es)
+ Data.Effect.OpenUnion: prefixFor1 :: forall fs x es e. KnownLength fs => Membership e es -> Membership e (Each fs x ++ es)
+ Data.Effect.OpenUnion: prefixLen :: Suffix es es' => Int
+ Data.Effect.OpenUnion: prefixLenUnder :: SuffixUnder es es' => Int
+ Data.Effect.OpenUnion: project :: Elem e order => Membership e es -> Union es f a -> Maybe (e f a)
+ Data.Effect.OpenUnion: projectAnyOrder :: forall e es f a. HFunctor e => Membership e es -> Union es f a -> Maybe (e f a)
+ Data.Effect.OpenUnion: reifyLength :: KnownLength xs => Int
+ Data.Effect.OpenUnion: shrinkOrdership :: Ordership o e f g -> Ordership (OrderOf e) e f g
+ Data.Effect.OpenUnion: splitFor :: forall es es' e r. KnownLength es => (Membership e es -> r) -> (Membership e es' -> r) -> Membership e (es ++ es') -> r
+ Data.Effect.OpenUnion: splitUnion :: forall es es' es'' f a. KnownLength es => (forall e. Membership e es -> Membership e es'') -> (forall e. Membership e es' -> Membership e es'') -> Union (es ++ es') f a -> Union es'' f a
+ Data.Effect.OpenUnion: suffixFor :: forall es' es e. Membership e es -> Membership e (es ++ es')
+ Data.Effect.OpenUnion: type FindByLabel label e es = MemberBy LabelResolver label e es
+ Data.Effect.OpenUnion: type Has key e es = MemberBy KeyResolver (KeyDiscriminator key) (e # key) es
+ Data.Effect.OpenUnion: type KnownIndex i es = (KnownNat i, KnownOrder (At i es))
+ Data.Effect.OpenUnion: type KnownOrder e = Elem e (OrderOf e)
+ Data.Effect.OpenUnion: type MemberBy resolver dscr e es = (FindBy resolver dscr (Discriminator resolver (HeadOf es)) e es, ErrorIfNotFound resolver dscr (Discriminator resolver (HeadOf es)) e es es, KnownOrder e)
+ Data.Effect.OpenUnion: type WeakenHOEs es = (WeakenHOEs_ es 0 (OrderOf (HeadOf es)), FOEs (RemoveHOEs es))
+ Data.Effect.OpenUnion: type e `In` es = MemberBy IdentityResolver (IdentityDiscriminator e) e es
+ Data.Effect.OpenUnion: type family Each (fs :: [k -> Effect]) x
+ Data.Effect.OpenUnion: unbundleUnion :: forall es es' f a. KnownLength es => Union (Union es ': es') f a -> Union (es ++ es') f a
+ Data.Effect.OpenUnion: union :: (forall e o g. Membership e es -> Ordership o e f g -> e g a -> r) -> Union es f a -> r
+ Data.Effect.OpenUnion: weaken :: Union es f a -> Union (e ': es) f a
+ Data.Effect.OpenUnion: weakenFor :: Membership e es -> Membership e (e' ': es)
+ Data.Effect.OpenUnion: weakenHOEs :: forall es f a. WeakenHOEs es => Union (RemoveHOEs es) f a -> Union es f a
+ Data.Effect.OpenUnion: weakenHOEsFor :: forall es e. WeakenHOEs es => Membership e (RemoveHOEs es) -> Membership e es
+ Data.Effect.OpenUnion: weakens :: Suffix es es' => Union es f a -> Union es' f a
+ Data.Effect.OpenUnion: weakensFor :: forall es es' e. Suffix es es' => Membership e es -> Membership e es'
+ Data.Effect.OpenUnion: weakensUnder :: SuffixUnder es es' => Union es f a -> Union es' f a
+ Data.Effect.OpenUnion: weakensUnderFor :: forall es es' e. SuffixUnder es es' => Membership e es -> Membership e es'
+ Data.Effect.Tag: data TaggedLabel tag (label :: Type)
+ Data.Effect.Tag: infixl 7 #
+ Data.Effect.Tag: instance forall k (e :: Data.Effect.Effect) (tag :: k). Data.Effect.FirstOrder e => Data.Effect.FirstOrder (Data.Effect.Tag.Tagged tag e)
+ Data.Effect.Tag: instance forall k (tag :: k) (e :: Data.Effect.Effect) (f :: * -> *). Data.Foldable.Foldable (e f) => Data.Foldable.Foldable (Data.Effect.Tag.Tagged tag e f)
+ Data.Effect.Tag: instance forall k (tag :: k) (e :: Data.Effect.Effect) (f :: * -> *). Data.Traversable.Traversable (e f) => Data.Traversable.Traversable (Data.Effect.Tag.Tagged tag e f)
+ Data.Effect.Tag: instance forall k (tag :: k) (e :: Data.Effect.Effect) (f :: * -> *). GHC.Base.Functor (e f) => GHC.Base.Functor (Data.Effect.Tag.Tagged tag e f)
+ Data.Effect.Tag: instance forall k (tag :: k) (e :: Data.Effect.Effect). Data.Effect.HFunctor.HFunctor e => Data.Effect.HFunctor.HFunctor (Data.Effect.Tag.Tagged tag e)
+ Data.Effect.Tag: newtype Tagged tag (e :: Effect) f a
+ Data.Effect.Tag: type e # tag = Tagged tag e
- Control.Effect: infix 2 <<:
+ Control.Effect: infix 2 ~~>
- Control.Effect: type (<<:) = SendHOE
+ Control.Effect: type (h :: (Type -> Type) -> Type -> Type) $$ f = h f
- Control.Effect: type (f :: Type -> Type) ~> (g :: Type -> Type) = forall x. () => f x -> g x
+ Control.Effect: type f ~> g = forall (x :: Type). f x -> g x
- Data.Effect: data Nop a
+ Data.Effect: data Nop :: Effect
- Data.Effect.HFunctor: class HFunctor (h :: Type -> Type -> Type -> Type)
+ Data.Effect.HFunctor: class HFunctor (ff :: (Type -> Type) -> Type -> Type)
- Data.Effect.HFunctor: hfmap :: forall (f :: Type -> Type) (g :: Type -> Type). HFunctor h => (f :-> g) -> h f :-> h g
+ Data.Effect.HFunctor: hfmap :: HFunctor ff => (forall x. f x -> g x) -> ff f a -> ff g a
- Data.Effect.HFunctor.HCont: HCont :: ((f ~> b) -> ff b a) -> HCont (ff :: (Type -> Type) -> Type -> Type) (b :: Type -> Type) (f :: Type -> Type) a
+ Data.Effect.HFunctor.HCont: HCont :: ((f ~> b) -> ff b a) -> HCont ff b f (a :: Type)
- Data.Effect.HFunctor.HCont: [unHCont] :: HCont (ff :: (Type -> Type) -> Type -> Type) (b :: Type -> Type) (f :: Type -> Type) a -> (f ~> b) -> ff b a
+ Data.Effect.HFunctor.HCont: [unHCont] :: HCont ff b f (a :: Type) -> (f ~> b) -> ff b a
- Data.Effect.HFunctor.HCont: newtype HCont (ff :: Type -> Type -> Type -> Type) (b :: Type -> Type) (f :: Type -> Type) a
+ Data.Effect.HFunctor.HCont: newtype HCont ff b f (a :: Type)
- Data.Effect.Tag: Tag :: ins a -> Tag (ins :: EffectF) (tag :: k) a
+ Data.Effect.Tag: Tag :: e f a -> Tagged tag (e :: Effect) f a
- Data.Effect.Tag: [unTag] :: Tag (ins :: EffectF) (tag :: k) a -> ins a
+ Data.Effect.Tag: [unTag] :: Tagged tag (e :: Effect) f a -> e f a
Files
- ChangeLog.md +6/−0
- data-effects-core.cabal +29/−17
- src/Control/Effect.hs +330/−24
- src/Control/Effect/Interpret.hs +197/−0
- src/Control/Effect/Key.hs +0/−66
- src/Control/Effect/Tag.hs +0/−70
- src/Control/Effect/Transform.hs +215/−0
- src/Data/Effect.hs +280/−22
- src/Data/Effect/HFunctor.hs +8/−41
- src/Data/Effect/HFunctor/HCont.hs +5/−6
- src/Data/Effect/Key.hs +0/−48
- src/Data/Effect/OpenUnion.hs +564/−0
- src/Data/Effect/Tag.hs +14/−34
- test/OpenUnion.hs +69/−0
ChangeLog.md view
@@ -9,3 +9,9 @@ * Remove the type operator for HCont. * Rename the terms "instruction" and "signature" to the simpler "FOE" and "HOE". * Support for GHC 9.8.2.++## 0.4.0.0 -- 2025-04-16++* The new v4 interface.+ * Unified first-order and higher-order effect interfaces.+ * Added a generic `Eff` carrier type.
data-effects-core.cabal view
@@ -1,6 +1,6 @@-cabal-version: 2.4+cabal-version: 3.0 name: data-effects-core-version: 0.2.0.0+version: 0.4.0.0 -- A short (one-line) description of the package. synopsis: A basic framework for effect systems based on effects represented by GADTs.@@ -15,12 +15,12 @@ -- The license under which the package is released. license: MPL-2.0 license-file: LICENSE-author: Sayo Koyoneda <ymdfield@outlook.jp>-maintainer: Sayo Koyoneda <ymdfield@outlook.jp>+author: Sayo contributors <ymdfield@outlook.jp>+maintainer: ymdfield <ymdfield@outlook.jp> -- A copyright notice. copyright:- 2023-2024 Sayo Koyoneda+ 2023-2025 Sayo contributors category: Control, Effect @@ -29,27 +29,30 @@ NOTICE README.md -tested-with:- GHC == 9.8.2- GHC == 9.4.1- GHC == 9.2.8+tested-with: GHC == {9.2.8, 9.4.8, 9.6.7, 9.8.4, 9.10.1, 9.12.2} +common warnings+ ghc-options: -Wall -Wredundant-constraints+ source-repository head type: git location: https://github.com/sayo-hs/data-effects- tag: v0.2.0+ tag: v0.4.0 subdir: data-effects-core library+ import: warnings+ exposed-modules: Data.Effect+ -- Data.Effect.OpenUnion Data.Effect.Tag- Data.Effect.Key Data.Effect.HFunctor Data.Effect.HFunctor.HCont+ Data.Effect.OpenUnion Control.Effect- Control.Effect.Tag- Control.Effect.Key+ Control.Effect.Interpret+ Control.Effect.Transform -- Modules included in this executable, other than Main. -- other-modules:@@ -57,9 +60,12 @@ -- LANGUAGE extensions used by modules in this package. -- other-extensions: build-depends:- base >= 4.16.4 && < 4.21,- compdata >= 0.13.1 && < 0.14,+ base >= 4.16.4 && < 4.22, mtl >= 2.2.2 && < 2.4,+ kan-extensions,+ free,+ unliftio,+ primitive, hs-source-dirs: src ghc-options: -Wall@@ -75,16 +81,21 @@ RecordWildCards, DefaultSignatures - test-suite test+ import: warnings+ main-is: Driver.hs hs-source-dirs: test build-depends: data-effects-core, base, tasty >= 1.4 && < 1.6,- tasty-hunit ^>= 0.10,+ tasty-hspec ^>= 1.2,+ hspec >= 2.5 && < 2.12, + other-modules:+ OpenUnion+ type: exitcode-stdio-1.0 build-tool-depends:@@ -101,3 +112,4 @@ FunctionalDependencies, RecordWildCards, DefaultSignatures+
src/Control/Effect.hs view
@@ -1,44 +1,350 @@--- This Source Code Form is subject to the terms of the Mozilla Public--- License, v. 2.0. If a copy of the MPL was not distributed with this--- file, You can obtain one at https://mozilla.org/MPL/2.0/.+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE QuantifiedConstraints #-}+{-# LANGUAGE UndecidableInstances #-} +-- SPDX-License-Identifier: MPL-2.0+ {- |-Copyright : (c) 2023-2024 Sayo Koyoneda+Copyright : (c) 2023-2025 Sayo contributors License : MPL-2.0 (see the file LICENSE) Maintainer : ymdfield@outlook.jp-Stability : experimental-Portability : portable -} module Control.Effect where -import Data.Effect (EffectF, EffectH, LiftFOE (unliftFOE))+import Control.Alternative.Free qualified as Tree+import Control.Alternative.Free.Final qualified as Final+import Control.Applicative (Alternative, empty, (<|>))+import Control.Applicative.Free qualified as Tree+import Control.Applicative.Free.Fast qualified as Fast+import Control.Applicative.Free.Final qualified as Final+import Control.Monad (MonadPlus)+import Control.Monad.Cont qualified as Cont+import Control.Monad.Except (MonadError, catchError, throwError)+import Control.Monad.Fix (MonadFix, mfix)+import Control.Monad.IO.Class (MonadIO, liftIO)+import Control.Monad.RWS (MonadRWS)+import Control.Monad.Reader (MonadReader (ask), local)+import Control.Monad.State (MonadState, get, put)+import Control.Monad.Writer (MonadWriter, listen, tell)+import Control.Monad.Writer qualified as Writer+import Data.Effect (+ Ask (Ask),+ AskLabel,+ CC (Jump, SubFork),+ Catch (Catch),+ ChooseH (ChooseH),+ Emb (Emb),+ Empty (Empty),+ Fail (Fail),+ Fix (Efix),+ Local (Local),+ State (Get, Put),+ StateLabel,+ Tell (Tell),+ TellLabel,+ Throw (Throw),+ ThrowLabel,+ UnliftBase (WithRunInBase),+ UnliftIO,+ WriterH (Listen),+ )+import Data.Effect.OpenUnion (+ At,+ FindByLabel,+ Has,+ IdentityResolver,+ In,+ KeyDiscriminator,+ KeyResolver,+ KnownIndex,+ KnownOrder,+ LabelResolver,+ Membership,+ Union,+ hfmapUnion,+ inject,+ membership,+ membershipAt,+ type (:>),+ )+import Data.Effect.Tag (Tagged (Tag), type (#))+import Data.Functor.Coyoneda (Coyoneda (Coyoneda), hoistCoyoneda, liftCoyoneda, lowerCoyoneda) import Data.Kind (Type)+import Data.Tuple (swap)+import UnliftIO qualified as IO --- | A type class that represents the ability to send an first-order effect @ins@ to carrier @f@.-class SendFOE (ins :: EffectF) f where- -- | Send an /instruction/ @ins@ to carrier @f@.- sendFOE :: ins a -> f a+newtype Eff ff es a = Eff {unEff :: ff (Union es (Eff ff es)) a} --- | The operator version of `SendFOE`.-type (<:) = SendFOE+perform :: forall e es ff a c. (e :> es, Free c ff) => e (Eff ff es) a -> Eff ff es a+perform = sendFor $ membership @LabelResolver+{-# INLINE perform #-} -infix 2 <:+perform' :: forall key e es ff a c. (Has key e es, Free c ff) => e (Eff ff es) a -> Eff ff es a+perform' = sendFor (membership @KeyResolver @(KeyDiscriminator key)) . Tag+{-# INLINE perform' #-} --- | A type class that represents the ability to send a higher-order effect @sig@ to carrier @f@.-class SendHOE (sig :: EffectH) f where- -- | Send a higher-order effect @sig@ to carrier @f@.- sendHOE :: sig f a -> f a+perform'' :: forall tag e es ff a c. (e # tag :> es, Free c ff) => e (Eff ff es) a -> Eff ff es a+perform'' = perform . Tag @tag+{-# INLINE perform'' #-} --- | The operator version of `SendHOE`.-type (<<:) = SendHOE+send :: forall e es ff a c. (e `In` es, Free c ff) => e (Eff ff es) a -> Eff ff es a+send = sendFor $ membership @IdentityResolver+{-# INLINE send #-} -infix 2 <<:+sendAt :: forall i es ff a c. (KnownIndex i es, Free c ff) => At i es (Eff ff es) a -> Eff ff es a+sendAt = sendFor $ membershipAt @i+{-# INLINE sendAt #-} -instance (SendFOE ins f) => SendHOE (LiftFOE ins) f where- sendHOE = sendFOE . unliftFOE- {-# INLINE sendHOE #-}+sendFor+ :: forall e es ff a c+ . (KnownOrder e, Free c ff)+ => Membership e es+ -> e (Eff ff es) a+ -> Eff ff es a+sendFor i = Eff . liftFree . inject i+{-# INLINE sendFor #-} +emb :: forall f es ff a c. (Emb f :> es, Free c ff) => f a -> Eff ff es a+emb = perform . Emb+{-# INLINE emb #-}+ -- | A natural transformation. type f ~> g = forall (x :: Type). f x -> g x infixr 2 ~>++type e ~~> f = e f ~> f++infix 2 ~~>++infixr 3 $+infixr 4 $$++-- | Type-level infix applcation for functors.+type (f :: Type -> Type) $ a = f a++-- | Type-level infix applcation for higher-order functors.+type (h :: (Type -> Type) -> Type -> Type) $$ f = h f++instance+ (FindByLabel AskLabel (Ask r) es, Local r :> es, Monad (Eff ff es), Free c ff)+ => MonadReader r (Eff ff es)+ where+ ask = perform Ask+ local f a = perform $ Local f a+ {-# INLINE ask #-}+ {-# INLINE local #-}++instance+ (FindByLabel TellLabel (Tell w) es, WriterH w :> es, Monoid w, Monad (Eff ff es), Free c ff)+ => MonadWriter w (Eff ff es)+ where+ tell = perform . Tell+ listen a = fmap swap $ perform $ Listen a+ pass = pass . fmap swap+ {-# INLINE tell #-}+ {-# INLINE listen #-}++{- |+For a given scope, uses the function (the first component of the pair returned+by that scope) to modify the accumulated value of that scope, and then+accumulates the result into the current outer scope.++@+pass m = do+ (w, (f, a)) <- listen m+ tell $ f w+ pure a+@+-}+pass+ :: forall w a es ff c+ . (Tell w :> es, WriterH w :> es, Monad (Eff ff es), Free c ff)+ => Eff ff es (w -> w, a)+ -> Eff ff es a+pass m = do+ (w, (f, a)) <- perform $ Listen m+ perform $ Tell $ f w+ pure a+{-# INLINE pass #-}++instance (FindByLabel StateLabel (State s) es, Monad (Eff ff es), Free c ff) => MonadState s (Eff ff es) where+ get = perform Get+ put = perform . Put+ {-# INLINE get #-}+ {-# INLINE put #-}++instance+ ( FindByLabel AskLabel (Ask r) es+ , Local r :> es+ , FindByLabel TellLabel (Tell w) es+ , WriterH w :> es+ , FindByLabel StateLabel (State s) es+ , Monoid w+ , Monad (Eff ff es)+ , Free c ff+ )+ => MonadRWS r w s (Eff ff es)++instance+ (FindByLabel ThrowLabel (Throw e) es, Catch e :> es, Monad (Eff ff es), Free c ff)+ => MonadError e (Eff ff es)+ where+ throwError = perform . Throw+ catchError a hdl = perform $ Catch a hdl+ {-# INLINE throwError #-}+ {-# INLINE catchError #-}++instance+ (Empty :> es, ChooseH :> es, Applicative (Eff ff es), Free c ff)+ => Alternative (Eff ff es)+ where+ empty = perform Empty+ a <|> b = perform $ ChooseH a b+ {-# INLINE empty #-}+ {-# INLINE (<|>) #-}++instance (Empty :> es, ChooseH :> es, Monad (Eff ff es), Free c ff) => MonadPlus (Eff ff es)++instance (CC ref :> es, Monad (Eff ff es), Free c ff) => Cont.MonadCont (Eff ff es) where+ callCC = callCC_+ {-# INLINE callCC #-}++sub+ :: forall ref a b es ff c+ . (CC ref :> es, Monad (Eff ff es), Free c ff)+ => (ref a -> Eff ff es b)+ -> (a -> Eff ff es b)+ -> Eff ff es b+sub p q = perform SubFork >>= either p q+{-# INLINE sub #-}++callCC_+ :: forall ref a b es ff c+ . (CC ref :> es, Monad (Eff ff es), Free c ff)+ => ((a -> Eff ff es b) -> Eff ff es a)+ -> Eff ff es a+callCC_ f = sub (f . jump) pure+ where+ jump ref x = perform $ Jump ref x+{-# INLINE callCC_ #-}++instance (Emb IO :> es, Monad (Eff ff es), Free c ff) => MonadIO (Eff ff es) where+ liftIO = emb+ {-# INLINE liftIO #-}++instance (Fail :> es, Monad (Eff ff es), Free c ff) => MonadFail (Eff ff es) where+ fail = perform . Fail+ {-# INLINE fail #-}++instance (Fix :> es, Monad (Eff ff es), Free c ff) => MonadFix (Eff ff es) where+ mfix = perform . Efix+ {-# INLINE mfix #-}++instance+ (UnliftIO :> es, Emb IO :> es, Monad (Eff ff es), Free c ff)+ => IO.MonadUnliftIO (Eff ff es)+ where+ withRunInIO f = perform $ WithRunInBase f+ {-# INLINE withRunInIO #-}++-- Free++class (forall f. c (ff f)) => Free c (ff :: (Type -> Type) -> Type -> Type) | ff -> c where+ {-# MINIMAL liftFree, (runFree | (retract, hoist)) #-}++ liftFree :: f a -> ff f a+ runFree :: (c g) => (forall x. f x -> g x) -> ff f a -> g a+ retract :: (c f) => ff f a -> f a+ hoist :: (forall x. f x -> g x) -> ff f a -> ff g a++ runFree f = retract . hoist f+ retract = runFree id++ default hoist :: (c (ff g)) => (forall x. f x -> g x) -> ff f a -> ff g a+ hoist phi = runFree $ liftFree . phi++ {-# INLINE runFree #-}+ {-# INLINE retract #-}+ {-# INLINE hoist #-}++convertEff+ :: forall ff gg es a c c'+ . (Free c ff, Free c' gg, forall r. c (gg r))+ => Eff ff es a+ -> Eff gg es a+convertEff = go+ where+ go :: Eff ff es ~> Eff gg es+ go = Eff . hoist (hfmapUnion go) . convertFree . unEff+{-# INLINE convertEff #-}++convertFree :: (Free c ff, Free c' gg, c (gg r)) => ff r a -> gg r a+convertFree = runFree liftFree+{-# INLINE convertFree #-}++deriving instance (forall f. Functor (ff f)) => Functor (Eff ff es)+deriving instance (forall r. Applicative (ff r)) => Applicative (Eff ff es)+deriving instance (forall r. Monad (ff r)) => Monad (Eff ff es)++instance Free Functor Coyoneda where+ liftFree = liftCoyoneda+ runFree f (Coyoneda g x) = g <$> f x+ retract = lowerCoyoneda+ hoist = hoistCoyoneda++ {-# INLINE liftFree #-}+ {-# INLINE runFree #-}+ {-# INLINE retract #-}+ {-# INLINE hoist #-}++instance Free Applicative Tree.Ap where+ liftFree = Tree.liftAp+ runFree = Tree.runAp+ retract = Tree.retractAp+ hoist = Tree.hoistAp++ {-# INLINE liftFree #-}+ {-# INLINE runFree #-}+ {-# INLINE retract #-}+ {-# INLINE hoist #-}++instance Free Applicative Fast.Ap where+ liftFree = Fast.liftAp+ runFree = Fast.runAp+ retract = Fast.retractAp+ hoist = Fast.hoistAp++ {-# INLINE liftFree #-}+ {-# INLINE runFree #-}+ {-# INLINE retract #-}+ {-# INLINE hoist #-}++instance Free Applicative Final.Ap where+ liftFree = Final.liftAp+ runFree = Final.runAp+ retract = Final.retractAp+ hoist = Final.hoistAp++ {-# INLINE liftFree #-}+ {-# INLINE runFree #-}+ {-# INLINE retract #-}+ {-# INLINE hoist #-}++instance Free Alternative Tree.Alt where+ liftFree = Tree.liftAlt+ runFree = Tree.runAlt+ hoist = Tree.hoistAlt++ {-# INLINE liftFree #-}+ {-# INLINE runFree #-}+ {-# INLINE hoist #-}++instance Free Alternative Final.Alt where+ liftFree = Final.liftAlt+ runFree = Final.runAlt+ hoist = Final.hoistAlt++ {-# INLINE liftFree #-}+ {-# INLINE runFree #-}+ {-# INLINE hoist #-}
+ src/Control/Effect/Interpret.hs view
@@ -0,0 +1,197 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}++{-# HLINT ignore "Avoid lambda" #-}++-- SPDX-License-Identifier: MPL-2.0++{- |+Copyright : (c) 2025 Sayo contributors+License : MPL-2.0 (see the file LICENSE)+Maintainer : ymdfield@outlook.jp+-}+module Control.Effect.Interpret where++import Control.Effect (+ Eff (..),+ Free (liftFree),+ hoist,+ runFree,+ type (~>),+ type (~~>),+ )+import Data.Effect (Emb, getEmb)+import Data.Effect.OpenUnion (+ Has,+ In,+ KnownLength,+ KnownOrder,+ Membership,+ Suffix,+ Union,+ hfmapUnion,+ identityMembership,+ keyMembership,+ labelMembership,+ nil,+ project,+ weakens,+ (!++),+ (!:),+ (:>),+ type (++),+ )+import Data.Effect.Tag (unTag)+import Data.Functor.Identity (Identity, runIdentity)++runEff :: (Free c ff, c f) => Eff ff '[Emb f] a -> f a+runEff = runFree (getEmb !: nil) . unEff+{-# INLINE runEff #-}++runPure :: (Free c ff, c Identity) => Eff ff '[] a -> a+runPure = runIdentity . runFree nil . unEff+{-# INLINE runPure #-}++interpret+ :: forall e es ff a c+ . (KnownOrder e, Free c ff)+ => e ~~> Eff ff es+ -> Eff ff (e ': es) a+ -> Eff ff es a+interpret i = interpretAll $ i !: Eff . liftFree+{-# INLINE interpret #-}++reinterpret+ :: forall e es es' ff a c+ . (Suffix es es', KnownOrder e, Free c ff)+ => e ~~> Eff ff es'+ -> Eff ff (e ': es) a+ -> Eff ff es' a+reinterpret i = interpretAll $ i !: Eff . liftFree . weakens+{-# INLINE reinterpret #-}++interprets+ :: forall es r ff a c+ . (KnownLength es, Free c ff)+ => Union es ~~> Eff ff r+ -> Eff ff (es ++ r) a+ -> Eff ff r a+interprets i = interpretAll $ i !++ Eff . liftFree+{-# INLINE interprets #-}++reinterprets+ :: forall es r r' ff a c+ . (Suffix r r', KnownLength es, Free c ff)+ => (Union es (Eff ff r') ~> Eff ff r')+ -> Eff ff (es ++ r) a+ -> Eff ff r' a+reinterprets i = interpretAll $ i !++ Eff . liftFree . weakens @r+{-# INLINE reinterprets #-}++interpose+ :: forall e es ff a c+ . (e :> es, Free c ff)+ => e ~~> Eff ff es+ -> Eff ff es a+ -> Eff ff es a+interpose = interposeFor labelMembership+{-# INLINE interpose #-}++interposeOn+ :: forall key e es ff a c+ . (Has key e es, Free c ff)+ => e ~~> Eff ff es+ -> Eff ff es a+ -> Eff ff es a+interposeOn f = interposeFor (keyMembership @key) (f . unTag)+{-# INLINE interposeOn #-}++interposeIn+ :: forall e es ff a c+ . (e `In` es, Free c ff)+ => e ~~> Eff ff es+ -> Eff ff es a+ -> Eff ff es a+interposeIn = interposeFor identityMembership+{-# INLINE interposeIn #-}++interposeFor+ :: forall e es ff a c+ . (KnownOrder e, Free c ff)+ => Membership e es+ -> e ~~> Eff ff es+ -> Eff ff es a+ -> Eff ff es a+interposeFor i f =+ interpretAll \u ->+ case project i u of+ Just e -> f e+ Nothing -> Eff $ liftFree u+{-# INLINE interposeFor #-}++preinterpose+ :: forall e es ff a c+ . (e :> es, Free c ff)+ => e ~~> Eff ff es+ -> Eff ff es a+ -> Eff ff es a+preinterpose = preinterposeFor labelMembership+{-# INLINE preinterpose #-}++preinterposeOn+ :: forall key e es ff a c+ . (Has key e es, Free c ff)+ => e ~~> Eff ff es+ -> Eff ff es a+ -> Eff ff es a+preinterposeOn f = preinterposeFor (keyMembership @key) (f . unTag)+{-# INLINE preinterposeOn #-}++preinterposeIn+ :: forall e es ff a c+ . (e `In` es, Free c ff)+ => e ~~> Eff ff es+ -> Eff ff es a+ -> Eff ff es a+preinterposeIn = preinterposeFor identityMembership+{-# INLINE preinterposeIn #-}++preinterposeFor+ :: forall e es ff a c+ . (KnownOrder e, Free c ff)+ => Membership e es+ -> e ~~> Eff ff es+ -> Eff ff es a+ -> Eff ff es a+preinterposeFor i f = go+ where+ go :: Eff ff es ~> Eff ff es+ go (Eff a) = Eff $ (`runFree` a) \u ->+ hoist (hfmapUnion go) $ case project i u of+ Just e -> unEff $ f e+ Nothing -> liftFree u+{-# INLINE preinterposeFor #-}++interpretAll+ :: forall es es' ff a c+ . (Free c ff)+ => (Union es ~~> Eff ff es')+ -> Eff ff es a+ -> Eff ff es' a+interpretAll i = go+ where+ go :: Eff ff es ~> Eff ff es'+ go = Eff . runFree (unEff . i . hfmapUnion go) . unEff+{-# INLINE interpretAll #-}++iterAllEff+ :: forall es f ff a c+ . (Free c ff, c f)+ => Union es ~~> f+ -> Eff ff es a+ -> f a+iterAllEff i = go+ where+ go :: Eff ff es ~> f+ go = runFree (i . hfmapUnion go) . unEff+{-# INLINE iterAllEff #-}
− src/Control/Effect/Key.hs
@@ -1,66 +0,0 @@-{-# LANGUAGE AllowAmbiguousTypes #-}---- This Source Code Form is subject to the terms of the Mozilla Public--- License, v. 2.0. If a copy of the MPL was not distributed with this--- file, You can obtain one at https://mozilla.org/MPL/2.0/.--{- |-Copyright : (c) 2023-2024 Sayo Koyoneda-License : MPL-2.0 (see the file LICENSE)-Maintainer : ymdfield@outlook.jp-Stability : experimental-Portability : portable--}-module Control.Effect.Key where--import Control.Applicative (Alternative)-import Control.Effect (SendFOE (sendFOE), SendHOE (sendHOE))-import Control.Monad (MonadPlus)-import Control.Monad.Except (MonadError)-import Control.Monad.Fix (MonadFix)-import Control.Monad.IO.Class (MonadIO)-import Control.Monad.RWS (MonadRWS)-import Control.Monad.Reader (MonadReader)-import Control.Monad.State (MonadState)-import Control.Monad.Writer (MonadWriter)-import Data.Coerce (coerce)-import Data.Effect (EffectF, EffectH)-import Data.Effect.HFunctor (HFunctor, hfmap)-import Data.Kind (Type)--class SendFOEBy key (ins :: EffectF) f | key f -> ins where- sendFOEBy :: ins a -> f a--class SendHOEBy key (sig :: EffectH) f | key f -> sig where- sendHOEBy :: sig f a -> f a---- | A wrapper data type to represent sending an effect to the carrier @f@ with the specified key.-newtype ByKey key (f :: Type -> Type) a = ByKey {runByKey :: f a}- deriving newtype- ( Functor- , Applicative- , Alternative- , Monad- , MonadPlus- , MonadFix- , MonadIO- , MonadFail- , MonadReader r- , MonadWriter w- , MonadState s- , MonadRWS r w s- , MonadError e- )---- | Send all effects within the scope, keyed, to carrier @f@.-key :: forall key f a. ByKey key f a -> f a-key = runByKey-{-# INLINE key #-}--instance (SendFOEBy key ins f) => SendFOE ins (ByKey key f) where- sendFOE = ByKey . sendFOEBy @key- {-# INLINE sendFOE #-}--instance (SendHOEBy key sig f, HFunctor sig) => SendHOE sig (ByKey key f) where- sendHOE = ByKey . sendHOEBy @key . hfmap coerce- {-# INLINE sendHOE #-}
− src/Control/Effect/Tag.hs
@@ -1,70 +0,0 @@-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE UndecidableInstances #-}---- This Source Code Form is subject to the terms of the Mozilla Public--- License, v. 2.0. If a copy of the MPL was not distributed with this--- file, You can obtain one at https://mozilla.org/MPL/2.0/.--{- |-Copyright : (c) 2023-2024 Sayo Koyoneda-License : MPL-2.0 (see the file LICENSE)-Maintainer : ymdfield@outlook.jp-Stability : experimental-Portability : portable--}-module Control.Effect.Tag where--import Control.Applicative (Alternative)-import Control.Effect (SendFOE (sendFOE), SendHOE (sendHOE))-import Control.Effect.Key (SendFOEBy, SendHOEBy, sendFOEBy, sendHOEBy)-import Control.Monad (MonadPlus)-import Control.Monad.Except (MonadError)-import Control.Monad.Fix (MonadFix)-import Control.Monad.IO.Class (MonadIO)-import Control.Monad.RWS (MonadRWS)-import Control.Monad.Reader (MonadReader)-import Control.Monad.State (MonadState)-import Control.Monad.Writer (MonadWriter)-import Data.Coerce (coerce)-import Data.Effect.HFunctor (HFunctor, hfmap)-import Data.Effect.Tag (pattern T, pattern TH, type (#), type (##))-import Data.Kind (Type)---- | A wrapper data type to represent sending an effect to the carrier @f@ with the specified tag.-newtype ViaTag tag (f :: Type -> Type) a = ViaTag {runViaTag :: f a}- deriving newtype- ( Functor- , Applicative- , Alternative- , Monad- , MonadPlus- , MonadFix- , MonadIO- , MonadFail- , MonadReader r- , MonadWriter w- , MonadState s- , MonadRWS r w s- , MonadError e- )---- | Send all effects within the scope, tagged, to carrier @f@.-tag :: forall tag f a. ViaTag tag f a -> f a-tag = runViaTag-{-# INLINE tag #-}--instance (SendFOE (ins # tag) f) => SendFOE ins (ViaTag tag f) where- sendFOE = ViaTag . sendFOE . T @tag- {-# INLINE sendFOE #-}--instance (SendHOE (sig ## tag) f, HFunctor sig) => SendHOE sig (ViaTag tag f) where- sendHOE = ViaTag . sendHOE . TH @tag . hfmap coerce- {-# INLINE sendHOE #-}--instance (SendFOEBy key (ins # tag) f) => SendFOEBy key ins (ViaTag tag f) where- sendFOEBy = ViaTag . sendFOEBy @key . T @tag- {-# INLINE sendFOEBy #-}--instance (SendHOEBy key (sig ## tag) f, HFunctor sig) => SendHOEBy key sig (ViaTag tag f) where- sendHOEBy = ViaTag . sendHOEBy @key . TH @tag . hfmap coerce- {-# INLINE sendHOEBy #-}
+ src/Control/Effect/Transform.hs view
@@ -0,0 +1,215 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE PatternSynonyms #-}++-- SPDX-License-Identifier: MPL-2.0++{- |+Copyright : (c) 2025 Sayo contributors+License : MPL-2.0 (see the file LICENSE)+Maintainer : ymdfield@outlook.jp+-}+module Control.Effect.Transform where++import Control.Effect (Eff (..), Free, hoist, sendFor, type (~>))+import Control.Effect.Interpret (interposeFor, interpret, reinterpret)+import Data.Effect.OpenUnion (+ Each,+ Has,+ In,+ KnownLength,+ KnownOrder,+ Membership,+ RemoveHOEs,+ Suffix,+ SuffixUnder,+ Union,+ WeakenHOEs,+ hfmapUnion,+ identityMembership,+ inject,+ keyMembership,+ labelMembership,+ mapUnion,+ prefixFor,+ prefixFor1,+ suffixFor,+ weaken,+ weakenFor,+ weakenHOEs,+ weakens,+ weakensUnder,+ (!:),+ pattern Here,+ type (++),+ type (:>),+ )+import Data.Effect.Tag (Tagged (Tag), unTag, type (#))++raise :: forall e es a ff c. (Free c ff) => Eff ff es a -> Eff ff (e ': es) a+raise = raises+{-# INLINE raise #-}++raises :: forall es es' a ff c. (Suffix es es', Free c ff) => Eff ff es a -> Eff ff es' a+raises = transAll weakens+{-# INLINE raises #-}++raiseUnder :: forall e0 e1 es a ff c. (Free c ff) => Eff ff (e0 ': es) a -> Eff ff (e0 ': e1 ': es) a+raiseUnder = raisesUnder+{-# INLINE raiseUnder #-}++raisesUnder :: forall e es es' a ff c. (Suffix es es', Free c ff) => Eff ff (e ': es) a -> Eff ff (e ': es') a+raisesUnder = transAll weakensUnder+{-# INLINE raisesUnder #-}++raisesUnders :: forall es es' a ff c. (SuffixUnder es es', Free c ff) => Eff ff es a -> Eff ff es' a+raisesUnders = transAll weakensUnder+{-# INLINE raisesUnders #-}++onlyFOEs :: forall es a ff c. (Free c ff, WeakenHOEs es) => Eff ff (RemoveHOEs es) a -> Eff ff es a+onlyFOEs = transAll weakenHOEs+{-# INLINE onlyFOEs #-}++raisePrefix+ :: forall es' es a ff c+ . (KnownLength es', Free c ff)+ => Eff ff es a+ -> Eff ff (es' ++ es) a+raisePrefix = transAll $ mapUnion $ prefixFor @es'+{-# INLINE raisePrefix #-}++raiseSuffix+ :: forall es' es a ff c+ . (Free c ff)+ => Eff ff es a+ -> Eff ff (es ++ es') a+raiseSuffix = transAll $ mapUnion $ suffixFor @es'+{-# INLINE raiseSuffix #-}++raisePrefix1+ :: forall fs x es a ff c+ . (KnownLength fs, Free c ff)+ => Eff ff es a+ -> Eff ff (Each fs x ++ es) a+raisePrefix1 = transAll $ mapUnion $ prefixFor1 @fs @x+{-# INLINE raisePrefix1 #-}++subsume :: forall e es a ff c. (e `In` es, Free c ff) => Eff ff (e ': es) a -> Eff ff es a+subsume = transAll $ inject identityMembership !: id+{-# INLINE subsume #-}++subsumeUnder :: forall e1 e0 es a ff c. (e1 `In` es, KnownOrder e0, Free c ff) => Eff ff (e0 ': e1 ': es) a -> Eff ff (e0 ': es) a+subsumeUnder = transAll $ inject Here !: inject (weakenFor identityMembership) !: weaken+{-# INLINE subsumeUnder #-}++-- todo: generalize subsume by type-class++transform+ :: forall e e' es a ff c+ . (KnownOrder e, KnownOrder e', Free c ff)+ => (e (Eff ff (e' ': es)) ~> e' (Eff ff (e' ': es)))+ -> Eff ff (e ': es) a+ -> Eff ff (e' ': es) a+transform f = reinterpret $ sendFor Here . f+{-# INLINE transform #-}++translate+ :: forall e e' es a ff c+ . (KnownOrder e, e' :> es, Free c ff)+ => (e (Eff ff es) ~> e' (Eff ff es))+ -> Eff ff (e ': es) a+ -> Eff ff es a+translate = translateFor labelMembership+{-# INLINE translate #-}++translateOn+ :: forall key e e' es a ff c+ . (KnownOrder e, Has key e' es, Free c ff)+ => (e (Eff ff es) ~> e' (Eff ff es))+ -> Eff ff (e ': es) a+ -> Eff ff es a+translateOn f = translateFor (keyMembership @key) (Tag . f)+{-# INLINE translateOn #-}++translateIn+ :: forall e e' es a ff c+ . (KnownOrder e, e' `In` es, Free c ff)+ => (e (Eff ff es) ~> e' (Eff ff es))+ -> Eff ff (e ': es) a+ -> Eff ff es a+translateIn = translateFor identityMembership+{-# INLINE translateIn #-}++translateFor+ :: forall e e' es a ff c+ . (KnownOrder e, KnownOrder e', Free c ff)+ => Membership e' es+ -> (e (Eff ff es) ~> e' (Eff ff es))+ -> Eff ff (e ': es) a+ -> Eff ff es a+translateFor i f = interpret $ sendFor i . f+{-# INLINE translateFor #-}++rewrite+ :: forall e es a ff c+ . (e :> es, Free c ff)+ => (e (Eff ff es) ~> e (Eff ff es))+ -> Eff ff es a+ -> Eff ff es a+rewrite = rewriteFor labelMembership+{-# INLINE rewrite #-}++rewriteOn+ :: forall key e es a ff c+ . (Has key e es, Free c ff)+ => (e (Eff ff es) ~> e (Eff ff es))+ -> Eff ff es a+ -> Eff ff es a+rewriteOn f = rewriteFor (keyMembership @key) (Tag . f . unTag)+{-# INLINE rewriteOn #-}++rewriteIn+ :: forall e es a ff c+ . (e `In` es, Free c ff)+ => (e (Eff ff es) ~> e (Eff ff es))+ -> Eff ff es a+ -> Eff ff es a+rewriteIn = rewriteFor identityMembership+{-# INLINE rewriteIn #-}++rewriteFor+ :: forall e es a ff c+ . (KnownOrder e, Free c ff)+ => Membership e es+ -> (e (Eff ff es) ~> e (Eff ff es))+ -> Eff ff es a+ -> Eff ff es a+rewriteFor i f = interposeFor i (sendFor i . f)+{-# INLINE rewriteFor #-}++transAll+ :: forall es es' ff a c+ . (Free c ff)+ => (Union es (Eff ff es') ~> Union es' (Eff ff es'))+ -> Eff ff es a+ -> Eff ff es' a+transAll f = go+ where+ go :: Eff ff es ~> Eff ff es'+ go (Eff a) = Eff $ hoist (f . hfmapUnion go) a+{-# INLINE transAll #-}++tag+ :: forall tag e es a ff c+ . (KnownOrder e, KnownOrder (e # tag), Free c ff)+ => Eff ff (e ': es) a+ -> Eff ff (e # tag ': es) a+tag = transform Tag+{-# INLINE tag #-}++untag+ :: forall tag e es a ff c+ . (KnownOrder e, KnownOrder (e # tag), Free c ff)+ => Eff ff (e # tag ': es) a+ -> Eff ff (e ': es) a+untag = transform unTag+{-# INLINE untag #-}
src/Data/Effect.hs view
@@ -1,40 +1,298 @@--- This Source Code Form is subject to the terms of the Mozilla Public--- License, v. 2.0. If a copy of the MPL was not distributed with this--- file, You can obtain one at https://mozilla.org/MPL/2.0/.+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE QuantifiedConstraints #-} +-- SPDX-License-Identifier: MPL-2.0+ {- |-Copyright : (c) 2023-2024 Sayo Koyoneda- (c) 2023 Casper Bach Poulsen and Cas van der Rest+Copyright : (c) 2023-2024 Sayo contributors License : MPL-2.0 (see the file LICENSE) Maintainer : ymdfield@outlook.jp-Stability : experimental-Portability : portable -} module Data.Effect where +import Data.Coerce (Coercible, coerce) import Data.Effect.HFunctor (HFunctor, hfmap) import Data.Kind (Type) --- | The kind of first-order effects.-type EffectF = Type -> Type+-- | The kind for effects.+type Effect = (Type -> Type) -> Type -> Type --- | The kind of higher-order effects.-type EffectH = (Type -> Type) -> Type -> Type+-- | An order of effect.+data EffectOrder = FirstOrder | HigherOrder+ deriving (Show, Eq, Ord) -{- | Lift first-order effects to higher-order effects.+type family OrderOf (e :: Effect) :: EffectOrder - Come from [heft-lang\/POPL2023\/haskell\/src\/Elab.hs]- (https://github.com/heft-lang/POPL2023/blob/74afe1d5ce0b491cffe40cc5c73a2a5ee6a94d9c/haskell/src/Elab.hs#L9-L10).+type family OrderCase (e :: EffectOrder) a b where+ OrderCase 'FirstOrder a b = a+ OrderCase 'HigherOrder a b = b++type family LabelOf (e :: Effect)++class+ ( OrderOf e ~ 'FirstOrder+ , forall f g a. Coercible (e f a) (e g a)+ ) =>+ FirstOrder (e :: Effect)++-- * Nop Effect++-- | A effect with no operations.+data Nop :: Effect+ deriving anyclass (FirstOrder)++data NopLabel+type instance LabelOf Nop = NopLabel+type instance OrderOf Nop = 'FirstOrder+instance HFunctor Nop where+ hfmap _ = \case {}+ {-# INLINE hfmap #-}++-- * Embedding Effect++newtype Emb e (f :: Type -> Type) (a :: Type) = Emb {getEmb :: e a}+ deriving anyclass (FirstOrder)+ deriving newtype (Functor, Applicative, Monad, Foldable)+ deriving stock (Traversable)++data EmbLabel (e :: Type -> Type)+type instance LabelOf (Emb e) = EmbLabel e+type instance OrderOf (Emb e) = 'FirstOrder+instance HFunctor (Emb e) where+ hfmap _ = coerce+ {-# INLINE hfmap #-}++newtype Unemb e a = Unemb {getUnemb :: forall f. e f a}++-- * Reader Effects++-- | An effect that holds a value of type @r@ in the context (environment).+data Ask r :: Effect where+ -- | Obtain a value from the environment.+ Ask :: Ask r f r++data AskLabel+type instance LabelOf (Ask r) = AskLabel+type instance OrderOf (Ask r) = 'FirstOrder+instance FirstOrder (Ask r)+instance HFunctor (Ask r) where+ hfmap _ = coerce+ {-# INLINE hfmap #-}++-- | An effect that locally modifies the value held in the environment.+data Local r :: Effect where+ -- | Locally modifies the value held in the environment.+ Local+ :: (r -> r)+ -- ^ A function that transforms the original value to the modified value.+ -> f a+ -- ^ The local scope where the modification is applied.+ -> Local r f a++data LocalLabel+type instance LabelOf (Local r) = LocalLabel+type instance OrderOf (Local r) = 'HigherOrder+instance HFunctor (Local r) where+ hfmap phi (Local f a) = Local f (phi a)+ {-# INLINE hfmap #-}++-- * State Effect++-- | An effect for holding mutable state values in the context.+data State s :: Effect where+ -- | Retrieves the current state value from the context.+ Get :: State s f s+ -- | Overwrites the state value in the context.+ Put :: s -> State s f ()++data StateLabel+type instance LabelOf (State s) = StateLabel+type instance OrderOf (State s) = 'FirstOrder+instance FirstOrder (State s)+instance HFunctor (State s) where+ hfmap _ = coerce+ {-# INLINE hfmap #-}++-- * Writer Effects++-- | An effect that can accumulate values monoidally in a context.+data Tell w :: Effect where+ -- | Accumulates new values to the cumulative value held in the context.+ Tell :: w -> Tell w f ()++data TellLabel+type instance LabelOf (Tell w) = TellLabel+type instance OrderOf (Tell w) = 'FirstOrder+instance FirstOrder (Tell w)+instance HFunctor (Tell w) where+ hfmap _ = coerce+ {-# INLINE hfmap #-}++-- | An effect that performs local operations on accumulations in the context on a per-scope basis.+data WriterH w :: Effect where+ -- | Obtains the accumulated value in the scope and returns it together as a pair.+ Listen+ :: f a+ -- ^ The scope from which to obtain the accumulation.+ -> WriterH w f (w, a)+ -- | Modifies the accumulation in the scope based on the given function.+ Censor+ :: (w -> w)+ -- ^ A function for modifying the accumulated value.+ -> f a+ -- ^ The scope where the modification is applied.+ -> WriterH w f a++data WriterHLabel+type instance LabelOf (WriterH w) = WriterHLabel+type instance OrderOf (WriterH w) = 'HigherOrder+instance HFunctor (WriterH w) where+ hfmap phi = \case+ Listen a -> Listen $ phi a+ Censor f a -> Censor f (phi a)+ {-# INLINE hfmap #-}++-- * Exception Effects++-- | An effect to escape from the normal control structure with an exception value of type @e@ in the middle of a context.+data Throw e :: Effect where+ -- | Throws an exception; that is, escapes from the normal control structure with an exception value in the middle of a context.+ Throw :: e -> Throw e f a++data ThrowLabel+type instance LabelOf (Throw e) = ThrowLabel+type instance OrderOf (Throw e) = 'FirstOrder+instance FirstOrder (Throw e)+instance HFunctor (Throw e) where+ hfmap _ = coerce+ {-# INLINE hfmap #-}++-- | An effect to catch exceptions.+data Catch e :: Effect where+ -- | Catches exceptions within a scope and processes them according to the given exception handler.+ Catch+ :: f a+ -- ^ The scope in which to catch exceptions.+ -> (e -> f a)+ -- ^ Exception handler. Defines the processing to perform when an exception is thrown within the scope.+ -> Catch e f a++data CatchLabel+type instance LabelOf (Catch w) = CatchLabel+type instance OrderOf (Catch w) = 'HigherOrder+instance HFunctor (Catch w) where+ hfmap phi (Catch a hdl) = Catch (phi a) (phi . hdl)+ {-# INLINE hfmap #-}++-- * Non-Determinism Effects++-- | An effect that eliminates a branch by causing the current branch context of a non-deterministic computation to fail.+data Empty :: Effect where+ -- | Eliminates a branch by causing the current branch context of a non-deterministic computation to fail.+ Empty :: Empty f a++data EmptyLabel+type instance LabelOf Empty = EmptyLabel+type instance OrderOf Empty = 'FirstOrder+instance FirstOrder Empty+instance HFunctor Empty where+ hfmap _ = coerce+ {-# INLINE hfmap #-}++-- | An effect that splits the computation into two branches.+data Choose :: Effect where+ -- | Splits the computation into two branches.+ -- As a result of executing @choose@, the world branches into one where `False` is returned and one where `True` is returned.+ Choose :: Choose f Bool++data ChooseLabel+type instance LabelOf Choose = ChooseLabel+type instance OrderOf Choose = 'FirstOrder+instance FirstOrder Choose+instance HFunctor Choose where+ hfmap _ = coerce+ {-# INLINE hfmap #-}++{- |+An effect that executes two branches as scopes.+A higher-order version of the t`Choose` effect. -}-newtype LiftFOE (ins :: EffectF) (f :: Type -> Type) a = LiftFOE {unliftFOE :: ins a}- deriving stock (Functor, Foldable, Traversable)+data ChooseH :: Effect where+ -- | Executes the given two scopes as branches.+ -- Even if one fails due to the `empty` operation, the whole does not fail as long as the other does not fail.+ ChooseH :: f a -> f a -> ChooseH f a -instance HFunctor (LiftFOE ins) where- hfmap _ (LiftFOE e) = LiftFOE e+data ChooseHLabel+type instance LabelOf ChooseH = ChooseHLabel+type instance OrderOf ChooseH = 'HigherOrder+instance HFunctor ChooseH where+ hfmap phi (ChooseH a b) = ChooseH (phi a) (phi b) {-# INLINE hfmap #-} --- | A first-order effect with no operations.-data Nop :: EffectF+-- * Fail Effect --- | A higher-order effect with no operations.-type LNop = LiftFOE Nop+data Fail :: Effect where+ Fail :: String -> Fail f a++data FailLabel+type instance LabelOf Fail = FailLabel+type instance OrderOf Fail = 'FirstOrder+instance FirstOrder Fail+instance HFunctor Fail where+ hfmap _ = coerce+ {-# INLINE hfmap #-}++-- * Fix Effect++data Fix :: Effect where+ Efix :: (a -> f a) -> Fix f a++data FixLabel+type instance LabelOf Fix = FixLabel+type instance OrderOf Fix = 'HigherOrder+instance HFunctor Fix where+ hfmap phi (Efix f) = Efix $ phi . f+ {-# INLINE hfmap #-}++-- * Unlift Effect++data UnliftBase b f (a :: Type) where+ WithRunInBase :: ((forall x. f x -> b x) -> b a) -> UnliftBase b f a++type UnliftIO = UnliftBase IO++data UnliftBaseLabel (b :: Type -> Type)+type instance LabelOf (UnliftBase b) = UnliftBaseLabel b+type instance OrderOf (UnliftBase b) = 'HigherOrder+instance HFunctor (UnliftBase b) where+ hfmap phi (WithRunInBase f) = WithRunInBase \run -> f $ run . phi+ {-# INLINE hfmap #-}++-- * CallCC Effect (Sub/Jump-based)++data CC ref :: Effect where+ SubFork :: CC ref f (Either (ref a) a)+ Jump :: ref a -> a -> CC ref f b++data CCLabel+type instance LabelOf (CC ref) = CCLabel+type instance OrderOf (CC ref) = 'FirstOrder+instance FirstOrder (CC ref)+instance HFunctor (CC ref) where+ hfmap _ = coerce+ {-# INLINE hfmap #-}++-- * Shift Effect++data Shift ans ref :: Effect where+ SubShiftFork :: Shift ans ref f (Either (ref a) a)+ Call :: ref a -> a -> Shift ans ref f ans+ Abort :: ans -> Shift ans ref f a++data ShiftLabel+type instance LabelOf (Shift ans ref) = ShiftLabel+type instance OrderOf (Shift ans ref) = 'FirstOrder+instance FirstOrder (Shift ans ref)+instance HFunctor (Shift ans ref) where+ hfmap _ = coerce+ {-# INLINE hfmap #-}
src/Data/Effect/HFunctor.hs view
@@ -1,46 +1,13 @@--- This Source Code Form is subject to the terms of the Mozilla Public--- License, v. 2.0. If a copy of the MPL was not distributed with this--- file, You can obtain one at https://mozilla.org/MPL/2.0/.+-- SPDX-License-Identifier: MPL-2.0 {- |-Copyright : (c) 2023 Sayo Koyoneda-License : MPL-2.0 (see the file LICENSE)+Copyright : (c) 2025 Sayo contributors+License : MPL-2.0 (see the LICENSE file) Maintainer : ymdfield@outlook.jp-Stability : experimental-Portability : portable--This module re-exports the `HFunctor` type class and related definitions from the `compdata`-package. For more details, please refer to the- [`compdata` documentation](https://hackage.haskell.org/package/compdata-0.13.0/docs/Data-Comp-Multi-HFunctor.html). -}-module Data.Effect.HFunctor (- HFunctor (..),- RemA (..),- DistAnn (..),- (:&:) (..),- (:=:),- (:<:),- Subsume (..),- Elem,- (:+:) (..),- caseH,- inj,- proj,- spl,-) where+module Data.Effect.HFunctor where -import Data.Comp.Multi.HFunctor (HFunctor (hfmap))-import Data.Comp.Multi.Ops (- DistAnn (injectA, projectA),- Elem,- RemA (remA),- Subsume (..),- caseH,- inj,- proj,- spl,- type (:&:) ((:&:)),- type (:+:) (Inl, Inr),- type (:<:),- type (:=:),- )+import Data.Kind (Type)++class HFunctor (ff :: (Type -> Type) -> Type -> Type) where+ hfmap :: (forall x. f x -> g x) -> ff f a -> ff g a
src/Data/Effect/HFunctor/HCont.hs view
@@ -1,25 +1,24 @@ {-# LANGUAGE QuantifiedConstraints #-} --- This Source Code Form is subject to the terms of the Mozilla Public--- License, v. 2.0. If a copy of the MPL was not distributed with this--- file, You can obtain one at https://mozilla.org/MPL/2.0/.+-- SPDX-License-Identifier: MPL-2.0 {- |-Copyright : (c) 2024 Sayo Koyoneda+Copyright : (c) 2024 Sayo contributors License : MPL-2.0 (see the file LICENSE) Maintainer : ymdfield@outlook.jp-Stability : experimental-Portability : portable -} module Data.Effect.HFunctor.HCont where import Control.Effect (type (~>))+import Data.Effect (EffectOrder (HigherOrder), OrderOf) import Data.Effect.HFunctor (HFunctor, hfmap) import Data.Kind (Type) -- | This represents that the effect @ff@ is finally interpreted as the base carrier @b@. newtype HCont ff b f (a :: Type) = HCont {unHCont :: (f ~> b) -> ff b a} deriving stock (Functor)++type instance OrderOf (HCont ff b) = 'HigherOrder instance HFunctor (HCont ff g) where hfmap phi (HCont f) = HCont \k -> f $ k . phi
− src/Data/Effect/Key.hs
@@ -1,48 +0,0 @@-{-# LANGUAGE PatternSynonyms #-}---- This Source Code Form is subject to the terms of the Mozilla Public--- License, v. 2.0. If a copy of the MPL was not distributed with this--- file, You can obtain one at https://mozilla.org/MPL/2.0/.--{- |-Copyright : (c) 2023-2024 Sayo Koyoneda-License : MPL-2.0 (see the file LICENSE)-Maintainer : ymdfield@outlook.jp-Stability : experimental-Portability : portable--}-module Data.Effect.Key where--import Data.Comp.Multi.HFunctor (HFunctor)-import Data.Effect (EffectF, EffectH)---- | Keyed first-order effect.-newtype Key key (ins :: EffectF) a = Key {unKey :: ins a}- deriving stock (Functor, Foldable, Traversable)---- | Keyed first-order effect.-type (#>) = Key--infixr 7 #>---- | Keyed first-order effect.-pattern K :: forall key ins a. ins a -> Key key ins a-pattern K e = Key e--{-# COMPLETE K #-}---- | Keyed higher-order effect.-newtype KeyH key (sig :: EffectH) f a = KeyH {unKeyH :: sig f a}- deriving stock (Functor, Foldable, Traversable)- deriving newtype (HFunctor)---- | Keyed higher-order effect.-type (##>) = KeyH--infixr 7 ##>---- | Keyed higher-order effect.-pattern KH :: forall key sig f a. sig f a -> KeyH key sig f a-pattern KH e = KeyH e--{-# COMPLETE KH #-}
+ src/Data/Effect/OpenUnion.hs view
@@ -0,0 +1,564 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ViewPatterns #-}+{-# OPTIONS_GHC -Wno-redundant-constraints #-}++-- SPDX-License-Identifier: MPL-2.0++{- |+Copyright : (c) 2024-2025 Sayo contributors+License : MPL-2.0 (see the file LICENSE)+Maintainer : ymdfield@outlook.jp+-}+module Data.Effect.OpenUnion where++import Control.Arrow ((&&&))+import Data.Coerce (coerce)+import Data.Data (Proxy (Proxy), (:~:) (Refl))+import Data.Effect (Effect, EffectOrder (FirstOrder, HigherOrder), FirstOrder, LabelOf, OrderCase, OrderOf)+import Data.Effect.HFunctor (HFunctor, hfmap)+import Data.Effect.Tag (type (#))+import Data.Kind (Constraint, Type)+import GHC.TypeLits (ErrorMessage (ShowType, Text, (:$$:), (:<>:)), KnownNat, Symbol, TypeError, natVal, type (+), type (-))+import Unsafe.Coerce (unsafeCoerce)++data Union (es :: [Effect]) (f :: Type -> Type) (a :: Type) where+ UnsafeUnion+ :: {-# UNPACK #-} !Int+ -- ^ A natural number tag to identify the element of the union.+ -> e g a+ -> {-# UNPACK #-} !EffectOrder+ -> (forall x. g x -> f x)+ -> Union es f a++instance HFunctor (Union es) where+ hfmap phi u@(UnsafeUnion n e order koi) =+ case order of+ FirstOrder -> unsafeCoerce u+ HigherOrder -> UnsafeUnion n e HigherOrder (phi . koi)+ {-# INLINE hfmap #-}++hfmapUnion :: (forall x. f x -> g x) -> Union es f a -> Union es g a+hfmapUnion phi u@(UnsafeUnion n e order koi) =+ case order of+ FirstOrder -> unsafeCoerce u+ HigherOrder -> UnsafeUnion n e HigherOrder (phi . koi)+{-# INLINE hfmapUnion #-}++class FOEs es+instance FOEs '[]+instance (FirstOrder e, FOEs es) => FOEs (e ': es)++coerceFOEs :: (FOEs es) => Union es f a -> Union es g a+coerceFOEs = unsafeCoerce+{-# INLINE coerceFOEs #-}++type instance OrderOf (Union es) = 'HigherOrder++newtype Membership (e :: Effect) (es :: [Effect]) = UnsafeMembership {unMembership :: Int}+ deriving stock (Eq, Show)++pattern Here :: Membership e (e ': es)+pattern Here = UnsafeMembership 0+{-# INLINE Here #-}++pattern There :: Membership e es -> Membership e (e ': es)+pattern There i <- ((UnsafeMembership . (`subtract` 1) &&& (/= 0)) . unMembership -> (i, True))+ where+ There (UnsafeMembership n) = UnsafeMembership (n + 1)+{-# INLINE There #-}++{-# COMPLETE Here, There #-}++weakenFor :: Membership e es -> Membership e (e' ': es)+weakenFor (UnsafeMembership n) = UnsafeMembership $ n + 1+{-# INLINE weakenFor #-}++mapUnion+ :: forall es es' f a+ . (forall e. Membership e es -> Membership e es')+ -> Union es f a+ -> Union es' f a+mapUnion f (UnsafeUnion n e order koi) =+ UnsafeUnion (unMembership $ f $ UnsafeMembership n) e order koi+{-# INLINE mapUnion #-}++membershipAt :: forall i es. (KnownNat i) => Membership (At i es) es+membershipAt = UnsafeMembership $ intVal @i+{-# INLINE membershipAt #-}++compareMembership :: Membership e es -> Membership e' es -> Maybe (e :~: e')+compareMembership (UnsafeMembership m) (UnsafeMembership n)+ | m == n = Just $ unsafeCoerce Refl+ | otherwise = Nothing++type family At i es where+ At 0 (e ': es) = e+ At n (e ': es) = At (n - 1) es+ At _ '[] = TypeError ('Text "Effect index out of range")++intVal :: forall n. (KnownNat n) => Int+intVal = fromIntegral $ natVal @n Proxy+{-# INLINE intVal #-}++data LabelResolver+data KeyResolver+data IdentityResolver++data KeyDiscriminator key+data NoKeyDiscriminator++data IdentityDiscriminator (e :: Effect)++type family Discriminator resolver (e :: Effect)+type instance Discriminator LabelResolver e = LabelOf e+type instance Discriminator KeyResolver e = KeyOf e+type instance Discriminator IdentityResolver e = IdentityDiscriminator e++type family KeyOf e where+ KeyOf (e # key) = KeyDiscriminator key+ KeyOf e = NoKeyDiscriminator++type family ResolverName resolver :: Symbol+type instance ResolverName LabelResolver = "label"+type instance ResolverName KeyResolver = "key"+type instance ResolverName IdentityResolver = "identity"++infix 4 :>+infix 4 `In`++type e :> es = MemberBy LabelResolver (Discriminator LabelResolver e) e es+type Has key e es = MemberBy KeyResolver (KeyDiscriminator key) (e # key) es+type e `In` es = MemberBy IdentityResolver (IdentityDiscriminator e) e es+type KnownIndex i es = (KnownNat i, KnownOrder (At i es))++type FindByLabel label e es = MemberBy LabelResolver label e es++type MemberBy resolver dscr e es =+ ( FindBy resolver dscr (Discriminator resolver (HeadOf es)) e es+ , ErrorIfNotFound resolver dscr (Discriminator resolver (HeadOf es)) e es es+ , KnownOrder e+ )++class+ (dscr ~ Discriminator resolver e, dscr' ~ Discriminator resolver (HeadOf r)) =>+ FindBy resolver dscr dscr' e r+ | resolver dscr dscr' r -> e+ where+ findBy :: Membership e r++instance+ (dscr ~ Discriminator resolver e, dscr ~ Discriminator resolver e', e ~ e')+ => FindBy resolver dscr dscr e (e' ': r)+ where+ findBy = Here+ {-# INLINE findBy #-}++instance+ {-# OVERLAPPABLE #-}+ ( dscr ~ Discriminator resolver e+ , dscr' ~ Discriminator resolver e'+ , FindBy resolver dscr (Discriminator resolver (HeadOf r)) e r+ )+ => FindBy resolver dscr dscr' e (e' ': r)+ where+ findBy = weakenFor $ findBy @resolver @dscr @(Discriminator resolver (HeadOf r)) @e @r+ {-# INLINE findBy #-}++membership+ :: forall resolver dscr e es+ . (FindBy resolver dscr (Discriminator resolver (HeadOf es)) e es)+ => Membership e es+membership = findBy @resolver @dscr @(Discriminator resolver (HeadOf es)) @e @es+{-# INLINE membership #-}++labelMembership+ :: forall e es+ . (FindBy LabelResolver (LabelOf e) (LabelOf (HeadOf es)) e es)+ => Membership e es+labelMembership = membership @LabelResolver+{-# INLINE labelMembership #-}++keyMembership+ :: forall key e es+ . (FindBy KeyResolver (KeyDiscriminator key) (KeyOf (HeadOf es)) (e # key) es)+ => Membership (e # key) es+keyMembership = membership @KeyResolver+{-# INLINE keyMembership #-}++identityMembership+ :: forall e es+ . (FindBy IdentityResolver (IdentityDiscriminator e) (IdentityDiscriminator (HeadOf es)) e es)+ => Membership e es+identityMembership = membership @IdentityResolver+{-# INLINE identityMembership #-}+class+ (dscr ~ Discriminator resolver e, dscr' ~ Discriminator resolver (HeadOf r)) =>+ ErrorIfNotFound resolver dscr dscr' (e :: Effect) (r :: [Effect]) (w :: [Effect])++instance+ ( TypeError+ ( 'Text "The effect ‘"+ ':<>: 'ShowType e+ ':<>: 'Text "’ does not exist within the effect list"+ ':$$: 'Text " ‘" ':<>: 'ShowType w ':<>: 'Text "’"+ ':$$: 'Text "Resolver: " ':<>: 'Text (ResolverName resolver)+ ':$$: 'Text "Discriminator: " ':<>: 'ShowType dscr+ )+ , dscr ~ Discriminator resolver e+ , dscr' ~ Discriminator resolver (HeadOf '[])+ )+ => ErrorIfNotFound resolver dscr dscr' e '[] w++instance+ (dscr ~ Discriminator resolver e, dscr ~ Discriminator resolver e', e ~ e')+ => ErrorIfNotFound resolver dscr dscr e (e' ': r) w++instance+ {-# OVERLAPPABLE #-}+ ( dscr ~ Discriminator resolver e+ , dscr' ~ Discriminator resolver e'+ , ErrorIfNotFound resolver dscr (Discriminator resolver (HeadOf r)) e r w+ )+ => ErrorIfNotFound resolver dscr dscr' e (e' ': r) w++instance+ {-# INCOHERENT #-}+ ( dscr ~ Discriminator resolver e+ , dscr' ~ Discriminator resolver (HeadOf r)+ )+ => ErrorIfNotFound resolver dscr dscr' e r w++type family HeadOf es where+ HeadOf (e ': es) = e++type KnownOrder e = Elem e (OrderOf e)++class (order ~ OrderOf e) => Elem e order where+ inject :: Membership e es -> e f a -> Union es f a+ project :: Membership e es -> Union es f a -> Maybe (e f a)+ (!:) :: (e f a -> r) -> (Union es f a -> r) -> Union (e ': es) f a -> r+ extract :: Union '[e] f a -> e f a++ infixr 5 !:++decomp :: (KnownOrder e, HFunctor e) => Union (e ': es) f a -> Either (e f a) (Union es f a)+decomp = Left !: Right+{-# INLINE decomp #-}++instance (FirstOrder e) => Elem e 'FirstOrder where+ inject :: forall es f a. Membership e es -> e f a -> Union es f a+ inject i = mkUnion i firstOrdership++ project+ :: forall es f a+ . Membership e es+ -> Union es f a+ -> Maybe (e f a)+ project i (UnsafeUnion n e _ _) =+ if n == unMembership i+ then Just $ unsafeCoerce e+ else Nothing++ (f !: g) (UnsafeUnion n e koi order) =+ if n == 0+ then f $ unsafeCoerce e+ else g $ UnsafeUnion (n - 1) e koi order++ extract (UnsafeUnion _ e _ _) = unsafeCoerce e++ {-# INLINE inject #-}+ {-# INLINE project #-}+ {-# INLINE (!:) #-}+ {-# INLINE extract #-}++instance (OrderOf e ~ 'HigherOrder, HFunctor e) => Elem e 'HigherOrder where+ inject :: forall es f a. Membership e es -> e f a -> Union es f a+ inject i = mkUnion i (higherOrdership id)++ project :: forall es f a. Membership e es -> Union es f a -> Maybe (e f a)+ project i (UnsafeUnion n e _ koi) =+ if n == unMembership i+ then Just $ hfmap koi (unsafeCoerce e)+ else Nothing++ (f !: g) (UnsafeUnion n e _ koi) =+ if n == 0+ then f $ hfmap koi (unsafeCoerce e)+ else g $ UnsafeUnion (n - 1) e HigherOrder koi++ extract (UnsafeUnion _ e _ koi) = hfmap koi (unsafeCoerce e)++ {-# INLINE inject #-}+ {-# INLINE project #-}+ {-# INLINE (!:) #-}+ {-# INLINE extract #-}++projectAnyOrder :: forall e es f a. (HFunctor e) => Membership e es -> Union es f a -> Maybe (e f a)+projectAnyOrder i (UnsafeUnion n e order koi) =+ if n == unMembership i+ then Just $ hfmapDynUnsafeCoerce order koi e+ else Nothing++infixr 5 `caseAnyOrder`++caseAnyOrder :: (HFunctor e) => (e f a -> r) -> (Union es f a -> r) -> Union (e ': es) f a -> r+(f `caseAnyOrder` g) (UnsafeUnion n e order koi) =+ if n == 0+ then f $ hfmapDynUnsafeCoerce order koi e+ else g $ UnsafeUnion (n - 1) e order koi++extractAnyOrder :: (HFunctor e) => Union es f a -> e f a+extractAnyOrder (UnsafeUnion _ e order koi) = hfmapDynUnsafeCoerce order koi e++{-# INLINE projectAnyOrder #-}+{-# INLINE caseAnyOrder #-}+{-# INLINE extractAnyOrder #-}++hfmapDynUnsafeCoerce :: (HFunctor e') => EffectOrder -> (forall x. f x -> g x) -> e f a -> e' g a+hfmapDynUnsafeCoerce order phi e = case order of+ FirstOrder -> unsafeCoerce e+ HigherOrder -> hfmap phi (unsafeCoerce e)+{-# INLINE hfmapDynUnsafeCoerce #-}++nil :: Union '[] f a -> r+nil _ = error "Effect system internal error: nil - An empty effect union, which should not be possible to create, has been created."++nilMembership :: Membership e '[] -> r+nilMembership _ = error "Effect system internal error: nil - An empty effect union membership, which should not be possible to create, has been created."++weakensFor :: forall es es' e. (Suffix es es') => Membership e es -> Membership e es'+weakensFor (UnsafeMembership n) = UnsafeMembership $ n + prefixLen @es @es'+{-# INLINE weakensFor #-}++class Suffix (es :: [Effect]) (es' :: [Effect]) where+ prefixLen :: Int++instance Suffix es es where+ prefixLen = 0+ {-# INLINE prefixLen #-}++instance {-# INCOHERENT #-} (Suffix es es') => Suffix es (e ': es') where+ prefixLen = prefixLen @es @es' + 1+ {-# INLINE prefixLen #-}++class SuffixUnder (es :: [Effect]) (es' :: [Effect]) where+ prefixLenUnder :: Int+ offset :: Int++instance (Suffix es es') => SuffixUnder es es' where+ prefixLenUnder = prefixLen @es @es'+ offset = 0++ {-# INLINE prefixLenUnder #-}+ {-# INLINE offset #-}++instance {-# INCOHERENT #-} (SuffixUnder es es') => SuffixUnder (e ': es) (e ': es') where+ prefixLenUnder = prefixLenUnder @es @es'+ offset = offset @es @es' + 1++ {-# INLINE prefixLenUnder #-}+ {-# INLINE offset #-}++weakensUnderFor :: forall es es' e. (SuffixUnder es es') => Membership e es -> Membership e es'+weakensUnderFor (UnsafeMembership n) =+ UnsafeMembership+ if n < offset @es @es'+ then n+ else n + prefixLenUnder @es @es'+{-# INLINE weakensUnderFor #-}++type family RemoveHOEs (es :: [Effect]) where+ RemoveHOEs '[] = '[]+ RemoveHOEs (e ': es) =+ OrderCase (OrderOf e) (e ': RemoveHOEs es) (RemoveHOEs es)++type WeakenHOEs es = (WeakenHOEs_ es 0 (OrderOf (HeadOf es)), FOEs (RemoveHOEs es))++class (orderOfHead ~ OrderOf (HeadOf es)) => WeakenHOEs_ es countF orderOfHead where+ -- | Example for '[H,F,F,H,H,F,H,F]+ --+ -- +----+-------+--------+----------------------++ -- | ix | order | countF | shifter accumulation |+ -- +====+=======+========+======================++ -- | 0 | H | 0 | 01234... -> 12345... |+ -- | 1 | F | 0 | 01234... -> 12345... |+ -- | 2 | F | 1 | 01234... -> 12345... |+ -- | 3 | H | 2 | 01234... -> 12456... |+ -- | 4 | H | 2 | 01234... -> 12567... |+ -- | 5 | F | 2 | 01234... -> 12567... |+ -- | 6 | H | 3 | 01234... -> 12578... |+ -- | 7 | F | 3 | 01234... -> 12578... |+ -- +----+-------+--------+----------------------++ foldHoeIndexShifter :: (Int -> Int) -> (Int -> Int)++instance (OrderOf (HeadOf '[]) ~ orderOfHead) => WeakenHOEs_ '[] countF orderOfHead where+ foldHoeIndexShifter = id+ {-# INLINE foldHoeIndexShifter #-}++instance (FirstOrder e, WeakenHOEs_ es (countF + 1) _orderOfHead) => WeakenHOEs_ (e ': es) countF 'FirstOrder where+ foldHoeIndexShifter = foldHoeIndexShifter @es @(countF + 1)+ {-# INLINE foldHoeIndexShifter #-}++instance+ (OrderOf e ~ 'HigherOrder, WeakenHOEs_ es countF _orderOfHead, KnownNat countF)+ => WeakenHOEs_ (e ': es) countF 'HigherOrder+ where+ foldHoeIndexShifter shifterAcc =+ foldHoeIndexShifter @es @countF \ix ->+ let shiftedIx = shifterAcc ix+ in if ix < intVal @countF+ then shiftedIx+ else shiftedIx + 1+ {-# INLINE foldHoeIndexShifter #-}++weaken :: Union es f a -> Union (e ': es) f a+weaken = mapUnion weakenFor+{-# INLINE weaken #-}++weakens :: (Suffix es es') => Union es f a -> Union es' f a+weakens = mapUnion weakensFor+{-# INLINE weakens #-}++weakensUnder :: (SuffixUnder es es') => Union es f a -> Union es' f a+weakensUnder = mapUnion weakensUnderFor+{-# INLINE weakensUnder #-}++weakenHOEsFor :: forall es e. (WeakenHOEs es) => Membership e (RemoveHOEs es) -> Membership e es+weakenHOEsFor = UnsafeMembership . foldHoeIndexShifter @es @0 id . unMembership+{-# INLINE weakenHOEsFor #-}++weakenHOEs :: forall es f a. (WeakenHOEs es) => Union (RemoveHOEs es) f a -> Union es f a+weakenHOEs = mapUnion weakenHOEsFor+{-# INLINE weakenHOEs #-}++type KnownLength :: forall {k}. [k] -> Constraint+class KnownLength xs where+ reifyLength :: Int++instance KnownLength '[] where+ reifyLength = 0+ {-# INLINE reifyLength #-}++instance (KnownLength xs) => KnownLength (x ': xs) where+ reifyLength = 1 + reifyLength @xs+ {-# INLINE reifyLength #-}++infixr 5 ++++type family (es :: [Effect]) ++ (es' :: [Effect]) where+ '[] ++ es = es+ (e ': es) ++ es' = e ': (es ++ es')++infixr 5 !++++(!++) :: forall es es' f a r. (KnownLength es) => (Union es f a -> r) -> (Union es' f a -> r) -> Union (es ++ es') f a -> r+(h !++ h') (UnsafeUnion n e o koi) =+ if n < reifyLength @es+ then h $ UnsafeUnion n e o koi+ else h' $ UnsafeUnion (n - reifyLength @es) e o koi+{-# INLINE (!++) #-}++bundleUnion+ :: forall es es' f a+ . (KnownLength es)+ => Union (es ++ es') f a+ -> Union (Union es ': es') f a+bundleUnion = union \i o e ->+ splitFor @es @es'+ (\j -> mkUnion Here (higherOrdership id) (mkUnion j o e))+ (\j -> mkUnion (weakenFor j) o e)+ i+{-# INLINE bundleUnion #-}++unbundleUnion+ :: forall es es' f a+ . (KnownLength es)+ => Union (Union es ': es') f a+ -> Union (es ++ es') f a+unbundleUnion = mapUnion (suffixFor @es') !: mapUnion (prefixFor @es)+{-# INLINE unbundleUnion #-}++splitUnion+ :: forall es es' es'' f a+ . (KnownLength es)+ => (forall e. Membership e es -> Membership e es'')+ -> (forall e. Membership e es' -> Membership e es'')+ -> Union (es ++ es') f a+ -> Union es'' f a+splitUnion injL injR = mapUnion $ splitFor @es @es' injL injR+{-# INLINE splitUnion #-}++mergeUnion+ :: forall es es' f a+ . (KnownLength es)+ => Either (Union es f a) (Union es' f a)+ -> Union (es ++ es') f a+mergeUnion = \case+ Left u -> mapUnion (suffixFor @es') u+ Right u -> mapUnion (prefixFor @es) u+{-# INLINE mergeUnion #-}++splitFor+ :: forall es es' e r+ . (KnownLength es)+ => (Membership e es -> r)+ -> (Membership e es' -> r)+ -> Membership e (es ++ es')+ -> r+splitFor f g (UnsafeMembership n)+ | n < l = f $ UnsafeMembership n+ | otherwise = g $ UnsafeMembership $ n - l+ where+ l = reifyLength @es+{-# INLINE splitFor #-}++suffixFor :: forall es' es e. Membership e es -> Membership e (es ++ es')+suffixFor = coerce+{-# INLINE suffixFor #-}++prefixFor :: forall es' es e. (KnownLength es') => Membership e es -> Membership e (es' ++ es)+prefixFor (UnsafeMembership n) = UnsafeMembership $ reifyLength @es' + n+{-# INLINE prefixFor #-}++type family Each (fs :: [k -> Effect]) x where+ Each (f ': fs) x = (f x ': Each fs x)+ Each '[] x = '[]++prefixFor1 :: forall fs x es e. (KnownLength fs) => Membership e es -> Membership e (Each fs x ++ es)+prefixFor1 (UnsafeMembership n) = UnsafeMembership $ reifyLength @fs + n+{-# INLINE prefixFor1 #-}++data Ordership (o :: EffectOrder) (e :: Effect) (f :: Type -> Type) (g :: Type -> Type) where+ UnsafeFirst :: Ordership 'FirstOrder e f g+ UnsafeHigher :: (forall x. g x -> f x) -> Ordership 'HigherOrder e f g++union :: (forall e o g. Membership e es -> Ordership o e f g -> e g a -> r) -> Union es f a -> r+union f (UnsafeUnion n e o koi) =+ let i = UnsafeMembership n+ in case o of+ FirstOrder -> f i UnsafeFirst e+ HigherOrder -> f i (UnsafeHigher koi) e+{-# INLINE union #-}++mkUnion :: Membership e es -> Ordership o e f g -> e g a -> Union es f a+mkUnion (UnsafeMembership i) o e = case o of+ UnsafeFirst -> UnsafeUnion i e FirstOrder undefined+ UnsafeHigher koi -> UnsafeUnion i e HigherOrder koi+{-# INLINE mkUnion #-}++firstOrdership :: (FirstOrder e) => Ordership 'FirstOrder e f g+firstOrdership = UnsafeFirst+{-# INLINE firstOrdership #-}++higherOrdership :: (OrderOf e ~ 'HigherOrder) => (forall x. g x -> f x) -> Ordership 'HigherOrder e f g+higherOrdership = UnsafeHigher+{-# INLINE higherOrdership #-}++shrinkOrdership :: Ordership o e f g -> Ordership (OrderOf e) e f g+shrinkOrdership = unsafeCoerce++continuationOfInterpretation :: Ordership 'HigherOrder e f g -> (forall x. g x -> f x)+continuationOfInterpretation (UnsafeHigher koi) = koi+{-# INLINE continuationOfInterpretation #-}
src/Data/Effect/Tag.hs view
@@ -1,48 +1,28 @@-{-# LANGUAGE PatternSynonyms #-}---- This Source Code Form is subject to the terms of the Mozilla Public--- License, v. 2.0. If a copy of the MPL was not distributed with this--- file, You can obtain one at https://mozilla.org/MPL/2.0/.+-- SPDX-License-Identifier: MPL-2.0 {- |-Copyright : (c) 2023-2024 Sayo Koyoneda+Copyright : (c) 2023-2024 Sayo contributors License : MPL-2.0 (see the file LICENSE) Maintainer : ymdfield@outlook.jp-Stability : experimental-Portability : portable -} module Data.Effect.Tag where -import Data.Comp.Multi.HFunctor (HFunctor)-import Data.Effect (EffectF, EffectH)---- | Tagged first-order effect.-newtype Tag (ins :: EffectF) tag a = Tag {unTag :: ins a}- deriving stock (Functor, Foldable, Traversable)---- | Tagged first-order effect.-type (#) = Tag--infixl 8 #---- | Tagged first-order effect.-pattern T :: forall tag ins a. ins a -> Tag ins tag a-pattern T e = Tag e--{-# COMPLETE T #-}+import Data.Effect (Effect, FirstOrder, LabelOf, OrderOf)+import Data.Effect.HFunctor (HFunctor)+import Data.Kind (Type) --- | Tagged higher-order effect.-newtype TagH (sig :: EffectH) tag f a = TagH {unTagH :: sig f a}+-- | Tagged effect.+newtype Tagged tag (e :: Effect) f a = Tag {unTag :: e f a} deriving stock (Functor, Foldable, Traversable) deriving newtype (HFunctor) --- | Tagged higher-order effect.-type (##) = TagH+type instance OrderOf (Tagged tag e) = OrderOf e+instance (FirstOrder e) => FirstOrder (Tagged tag e) -infixl 8 ##+type instance LabelOf (Tagged tag e) = TaggedLabel tag (LabelOf e)+data TaggedLabel tag (label :: Type) --- | Tagged higher-order effect.-pattern TH :: forall tag sig f a. sig f a -> TagH sig tag f a-pattern TH e = TagH e+-- | Tagged effect.+type e # tag = Tagged tag e -{-# COMPLETE TH #-}+infixl 7 #
+ test/OpenUnion.hs view
@@ -0,0 +1,69 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE QuantifiedConstraints #-}+{-# OPTIONS_GHC -Wno-redundant-constraints #-}+{-# OPTIONS_GHC -fconstraint-solver-iterations=16 #-}++-- SPDX-License-Identifier: MPL-2.0++module OpenUnion where++import Control.Effect (Eff, Free, perform)+import Data.Effect (Catch, Effect, LabelOf, Throw (Throw))+import Data.Effect.OpenUnion (Membership (UnsafeMembership), labelMembership, membershipAt, weakenHOEsFor, (:>))+import Data.Proxy (Proxy (Proxy))+import GHC.TypeNats (KnownNat, Natural, natVal)+import Test.Hspec (Spec, describe, it, shouldBe)++data A x :: Effect+data ALabel+type instance LabelOf (A x) = ALabel++data B x y :: Effect+data BLabel x+type instance LabelOf (B x y) = BLabel x++spec_membership :: Spec+spec_membership = describe "Open-Union Membership" do+ it "Membership (A 0) '[B 1 2, A 0] -> 1" $+ label1 `shouldBe` UnsafeMembership 1++ it "Membership (B 5 6) '[B 1 2, B 3 4, A 1, B 5 6, A 0] -> 3" $+ label2 `shouldBe` UnsafeMembership 3++ it "Membership (B 5 ?) '[B 1 2, B 3 4, A 1, B 5 6, A 0] --infer--> ?=6" $+ infer1 labelMembership `shouldBe` 6+ where+ label1 :: Membership (A 0) '[B 1 2, A 0]+ label1 = labelMembership++ label2 :: Membership (B 5 6) '[B 1 2, B 3 4, A 1, B 5 6, A 0]+ label2 = labelMembership++ infer1 :: forall x. (KnownNat x) => Membership (B 5 x) '[B 1 2, B 3 4, A 1, B 5 6, A 0] -> Natural+ infer1 _ = natVal @x Proxy++type F = Throw ()+type H = Catch ()++spec_onlyFOEs :: Spec+spec_onlyFOEs = describe "onlyFOEs index shift" do+ it "'[<F>, F , F , F ] -> '[ H ,<F>, F , H , H , F , H , F ]" $+ shiftIx ix0 `shouldBe` UnsafeMembership 1+ it "'[ F ,<F>, F , F ] -> '[ H , F ,<F>, H , H , F , H , F ]" $+ shiftIx ix1 `shouldBe` UnsafeMembership 2+ it "'[ F , F ,<F>, F ] -> '[ H , F , F , H , H ,<F>, H , F ]" $+ shiftIx ix2 `shouldBe` UnsafeMembership 5+ it "'[ F , F , F ,<F>] -> '[ H , F , F , H , H , F , H ,<F>]" $+ shiftIx ix3 `shouldBe` UnsafeMembership 7+ where+ shiftIx :: Membership e '[F, F, F, F] -> Membership e '[H, F, F, H, H, F, H, F]+ shiftIx = weakenHOEsFor++ ix0, ix1, ix2, ix3 :: Membership F '[F, F, F, F]+ ix0 = membershipAt @0+ ix1 = membershipAt @1+ ix2 = membershipAt @2+ ix3 = membershipAt @3++inferCompileTest :: (Throw () :> es, Catch () :> es, Free Monad ff) => Eff ff es a+inferCompileTest = perform $ Throw mempty