-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
handlerHide2? #3
Comments
I have been able to implement it like this: data ContextT e e' where
CTCons :: !(Marker ans) -> !(h e' ans) -> !(ContextT e e') -> ContextT e (h :* e)
CTId :: ContextT e e
CTCompose :: ContextT e' e'' -> ContextT e e' -> ContextT e e''
-- CTFun :: !(Context e -> Context e') -> ContextT e e'
-- apply a context transformer
applyT :: ContextT e e' -> Context e -> Context e'
applyT (CTCompose f g) ctx = applyT f (applyT g ctx)
applyT (CTCons m h g) ctx = CCons m h g ctx
applyT (CTId) ctx = ctx
--applyT (CTFun f) ctx = f ctx
{-# INLINE handlerHide2 #-}
handlerHide2
:: h (h' :* h'' :* e) ans -> Eff (h :* e) ans -> Eff (h' :* h'' :* e) ans
handlerHide2 h action = Eff
(\(CCons m1 h1 g1 (CCons m2 h2 g2 ctx')) -> prompt
(\m -> under
(CCons m h (CTCompose (CTCons m1 h1 g1) (CTCons m2 h2 g2)) ctx')
action
)
) Then you can also make it an instance of Category: instance Category ContextT where
id = CTId
(.) = CTCompose
{-# INLINE handlerHide2 #-}
handlerHide2
:: h (h' :* h'' :* e) ans -> Eff (h :* e) ans -> Eff (h' :* h'' :* e) ans
handlerHide2 h action = Eff
(\(CCons m1 h1 g1 (CCons m2 h2 g2 ctx')) ->
prompt
(\m -> under (CCons m h (CTCons m1 h1 g1 . CTCons m2 h2 g2) ctx') action)
) With this definition the original example can be written as: toLoggedHTTP :: Eff (Zooit :* e) a -> Eff (HTTP :* Logging :* e) a
toLoggedHTTP = handlerHide2 Zooit
{ listScenariosOp = function
(\() -> do
logMsg "Fetching a list of scenarios"
lines <$> httpGET "/scenarios"
)
} Now the |
I have been able to make a type family xs :++ ys where
() :++ ys = ys
(x :* xs) :++ ys = x :* xs :++ ys
data CLenSing c where
CLZero :: CLenSing ()
CLSucc :: CLenSing a -> CLenSing (b :* a)
class KnownCLen c where contextLength :: CLenSing c
instance KnownCLen () where contextLength = CLZero
instance KnownCLen xs => KnownCLen (x :* xs) where contextLength = CLSucc (contextLength @xs)
handlerHideN :: forall hs h e ans. KnownCLen hs => h (hs :++ e) ans -> Eff (h :* e) ans -> Eff (hs :++ e) ans
handlerHideN h action = Eff (go (contextLength @hs) CTId) where
go :: CLenSing hs' -> ContextT (hs' :++ e) (hs :++ e) -> Context (hs' :++ e) -> Ctl ans
go CLZero ct ctx' = prompt (\m -> under (CCons m h ct ctx') action)
go (CLSucc cl') ct (CCons m' g' h' ctx') = go cl' (CTCompose ct (CTCons m' g' h')) ctx' If you want the handlerHideN :: forall hs h e ans. KnownCLen hs => h (hs :++ e) ans -> Eff (h :* e) ans -> Eff (hs :++ e) ans
handlerHideN h action = Eff
$ (\(ct,ctx') -> prompt (\m -> under (CCons m h ct ctx') action))
. go (contextLength @hs)
where
go :: CLenSing hs' -> Context (hs' :++ e) -> (ContextT e (hs' :++ e), Context e)
go CLZero ctx' = (CTId, ctx')
go (CLSucc cl') (CCons m' g' h' ctx') = (CTCompose (CTCons m' g' h') ct, ctx'') where
~(ct, ctx'') = go cl' ctx' |
The solution with I am not sure about the general |
I'm trying to implement the
effect-zoo
scenarios to learn how to use this library. I'm stuck on the reinterpretation scenario. The scenario is that there is aZooit
effect that should be decomposed into aHTTP
and aLogging
effect. It is straightforward to write a naive solution:But now the
HTTP
andLogging
effects "leak" to the argument oftoLoggedHTTP
. If you only want to replace an effect by a single other effect, then you can usehandlerHide
, but I haven't been able to make that work with replacing one effect by two new effects. Is there a way to do this or do we need ahandlerHide2
function?The text was updated successfully, but these errors were encountered: