-
Is there any way to rewrite a function such as runState :: s -> Eff (State s ': es) a -> Eff es (a, s) So that the second parameter It's important because when the input function |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 1 reply
-
The second parameter being concrete is by design. The order of effects should remain abstract throughout your program, except when you are popping one of them off the stack, if you will. In other words, the order is determined by the order of the I think this is only a "problem" if you are relying on the concrete ordering of effects elsewhere in the codebase, which I believe is an anti-pattern. |
Beta Was this translation helpful? Give feedback.
-
@evanrelf thanks for the help. I don't think i'm understanding it. Especially in combination with #204 which was solved with the plugin for the easier case.
I think i should have been more clearer. Not to change the design of the In the other ticket #204 Shows i CAN use a polymorphic Here a part of my code type Eval es v = (Error EvalMonadError :> es, State (EvalMonadState v) :> es)
evalProg :: forall es v. (EvalTarget v) => [Proc] -> [v] -> String -> [v] -> Eff (Error String : es) (StateMachine v, [v])
evalProg procs vs main args =
let x :: Eval es v => Eff es [v] = (evalProc @v @es) main args
in runProg procs vs x -- Line 37: How to let runProg accept an x with constraints?
-- Also tried: in (runProg @es @v) procs vs x
evalProc :: forall v es. EvalTarget v => Eval es v => String -> [v] -> Eff es [v]
evalProc = undefined -- < .. snip .. more code ..>
runProg :: forall es a v b. [Proc] -> [v] -> Eff (State (EvalMonadState v) : Error EvalMonadError : es) a -> Eff (Error EvalMonadError : es) (StateMachine v, a)
runProg procs vs f = do
r <- raise $ runError (runState init_state f) -- raise because want to create a new Error some lines later
-- < .. snip .. more code ..>
The only solution i see here it to let |
Beta Was this translation helpful? Give feedback.
-
@evanrelf someone else had a look at it as well. We didn't solve it but this was the comment
Also tried putting an evalProg :: forall es v. (EvalTarget v) => [Proc] -> [v] -> String -> [v] -> Eff (Error String : es) (StateMachine v, [v])
evalProg procs vs main args =
let x :: Eval es v => Eff es [v] = (evalProc @v @es) main args
in (runProg @es @v) procs vs $ inject x no joy
|
Beta Was this translation helpful? Give feedback.
-
I think using a separate es2 is on the right track. The following code compiles for me (with stubs tossed in for the extra types). The interesting change is on the type Eval es v = (Error EvalMonadError :> es, State (EvalMonadState v) :> es)
evalProg :: forall es v. EvalTarget v => [Proc] -> [v] -> String -> [v] -> Eff (Error String : es) (StateMachine v, [v])
evalProg procs vs main args =
let x = ((evalProc @v @es2) main args :: forall es2. Eval es2 v => Eff es2 [v])
in runProg procs vs x -- Line 37: How to let runProg accept an x with constraints?
-- Also tried: in (runProg @es @v) procs vs x
evalProc :: forall v es. EvalTarget v => Eval es v => String -> [v] -> Eff es [v]
evalProc = undefined -- < .. snip .. more code ..>
runProg :: forall es a v b. [Proc] -> [v] -> Eff (State (EvalMonadState v) : Error EvalMonadError : es) a -> Eff (Error String : es) (StateMachine v, a)
runProg procs vs f = do
-- r <- raise $ runError (runState (init_state @v) f) -- raise because want to create a new Error some lines later
undefined
-- < .. snip .. more code ..> |
Beta Was this translation helpful? Give feedback.
I think using a separate es2 is on the right track. The following code compiles for me (with stubs tossed in for the extra types). The interesting change is on the
let x =....
line. The trick is making sure that x works with any effect stack instead of forcing it to be something specific. I also had to change the type signature of runProg slightly to get the same error as you. I'm guessing that was a typo, but let me know if not.