dep-t-advice 0.4.0.0 → 0.4.0.1
raw patch · 3 files changed
+27/−27 lines, 3 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Control.Monad.Dep.Advice: instance Control.Monad.Dep.Advice.Deceivable as newtyped e_ m r curried => Control.Monad.Dep.Advice.Deceivable (a : as) newtyped e_ m r (a -> curried)
- Control.Monad.Dep.Advice: instance GHC.Base.Monad m => Control.Monad.Dep.Advice.Deceivable '[] newtyped e_ m r (Control.Monad.Dep.DepT e_ m r)
+ Control.Monad.Dep.Advice: instance Control.Monad.Dep.Advice.Gullible as e e_ m r curried => Control.Monad.Dep.Advice.Gullible (a : as) e e_ m r (a -> curried)
+ Control.Monad.Dep.Advice: instance GHC.Base.Monad m => Control.Monad.Dep.Advice.Gullible '[] e e_ m r (Control.Monad.Dep.DepT e_ m r)
- Control.Monad.Dep.Advice: deceive :: forall as newtyped e_ m r curried. Deceivable as newtyped e_ m r curried => (e_ (DepT e_ m) -> newtyped) -> Deceived as newtyped e_ m r curried -> curried
+ Control.Monad.Dep.Advice: deceive :: forall as e e_ m r curried. Gullible as e e_ m r curried => (e_ (DepT e_ m) -> e) -> NewtypedEnv as e e_ m r curried -> curried
Files
- dep-t-advice.cabal +1/−1
- lib/Control/Monad/Dep/Advice.hs +20/−12
- lib/Control/Monad/Dep/Advice/Basic.hs +6/−14
dep-t-advice.cabal view
@@ -1,7 +1,7 @@ cabal-version: 3.0 name: dep-t-advice -version: 0.4.0.0 +version: 0.4.0.1 synopsis: Giving good advice to functions in a DepT environment. description: Companion to the dep-t package. Easily add behaviour to functions living in a DepT environment, whatever the number of arguments they might have.
lib/Control/Monad/Dep/Advice.hs view
@@ -549,17 +549,25 @@ in captureExistential evidence proxy tweakArgs tweakExecution -- -class Multicurryable as e_ m r curried => Deceivable as newtyped e_ m r curried where - type Deceived as newtyped e_ m r curried :: Type - _deceive :: (e_ (DepT e_ m) -> newtyped) -> Deceived as newtyped e_ m r curried -> curried +type Gullible :: + [Type] -> + Type -> + ((Type -> Type) -> Type) -> + (Type -> Type) -> + Type -> + Type -> + Constraint +class Multicurryable as e_ m r curried => Gullible as e e_ m r curried where + type NewtypedEnv as e e_ m r curried :: Type + _deceive :: (e_ (DepT e_ m) -> e) -> NewtypedEnv as e e_ m r curried -> curried -instance Monad m => Deceivable '[] newtyped e_ m r (DepT e_ m r) where - type Deceived '[] newtyped e_ m r (DepT e_ m r) = ReaderT newtyped m r +instance Monad m => Gullible '[] e e_ m r (DepT e_ m r) where + type NewtypedEnv '[] e e_ m r (DepT e_ m r) = ReaderT e m r _deceive f action = DepT (withReaderT f action) -instance Deceivable as newtyped e_ m r curried => Deceivable (a ': as) newtyped e_ m r (a -> curried) where - type Deceived (a ': as) newtyped e_ m r (a -> curried) = a -> Deceived as newtyped e_ m r curried - _deceive f g a = deceive @as @newtyped @e_ @m @r f (g a) +instance Gullible as e e_ m r curried => Gullible (a ': as) e e_ m r (a -> curried) where + type NewtypedEnv (a ': as) e e_ m r (a -> curried) = a -> NewtypedEnv as e e_ m r curried + _deceive f g a = deceive @as @e @e_ @m @r f (g a) -- | Makes a function see a newtyped version of the environment record, a version that might have different @HasX@ instances. -- @@ -628,12 +636,12 @@ -- already \"collapsed\" into 'DepT' won't work. Therefore, 'deceive' must be applied before any 'Advice'. -- deceive :: - forall as newtyped e_ m r curried. - Deceivable as newtyped e_ m r curried => + forall as e e_ m r curried. + Gullible as e e_ m r curried => -- | The newtype constructor that masks the \"true\" environment. - (e_ (DepT e_ m) -> newtyped) -> + (e_ (DepT e_ m) -> e) -> -- | A function to be deceived. It must be polymorphic over 'Control.Monad.Dep.MonadDep'. - Deceived as newtyped e_ m r curried -> + NewtypedEnv as e e_ m r curried -> -- | The deceived function, that has effects in 'DepT'. curried deceive = _deceive
lib/Control/Monad/Dep/Advice/Basic.hs view
@@ -65,8 +65,6 @@ -- | Makes functions discard their result and always return 'mempty'. -- --- Because it doesn't touch the arguments or require some effect from the --- environment, this 'Advice' is polymorphic on @ca@ and @cem@. returnMempty :: forall ca e_ m r. (Monad m, Monoid r) => Advice ca e_ m r returnMempty = makeExecutionAdvice @@ -78,11 +76,6 @@ -- | Given a 'Handle' and a prefix string, makes functions print their -- arguments to the 'Handle'. -- --- This advice uses 'MonadConstraint' to lift the 'MonadIO' constraint that --- applies only to the monad. --- --- Because it doesn't touch the return value of the advised function, this --- 'Advice' is polymorphic on @cr@. printArgs :: forall e_ m r. MonadIO m => Handle -> String -> Advice Show e_ m r printArgs h prefix = makeArgsAdvice @@ -99,7 +92,7 @@ -- Allows tweaking the environment that will be seen by the function and all of -- its sub-calls into dependencies. -- --- Note that perhaps this is __not__ what you want; often it's better to tweak +-- Perhaps this is __not__ what you want; often, it's better to tweak -- the environment for the current function only. For those cases, -- 'Control.Monad.Dep.Advice.deceive' might be a better fit. -- @@ -155,12 +148,11 @@ Just Refl -> any1 == any2 -- | --- Given the means for looking up and storing values in the underlying monad --- @m@, makes functions (inefficiently) cache their results. +-- Given the means for looking up and storing @r@ values in the underlying +-- monad @m@, makes functions (inefficiently) cache their results. -- --- Notice the equality constraints on the 'Advice'. This means that the monad --- @m@ and the result type @r@ are known and fixed before building the advice. --- Once built, the 'Advice' won't be polymorphic over them. +-- The monad @m@ and the result type @r@ must be known before building the +-- advice. So, once built, this 'Advice' won't be polymorphic over them. -- -- The implementation of this function makes use of the existential type -- parameter @u@ of 'makeAdvice', because the phase that processes the function @@ -192,7 +184,7 @@ -- A better implementation of this advice would likely use the \"async\" -- package instead of bare `forkIO`. -- --- And the @MustBe IO@ constraint could be relaxed to @MonadUnliftIO@. +-- The @IO@ monad could be generalized to @MonadUnliftIO@. doAsyncBadly :: forall ca e_ . Advice ca e_ IO () doAsyncBadly = makeExecutionAdvice (\action -> do e <- ask