Open eyeinsky opened 2 years ago
This works, for something..
= m
. Am I misunderstanding your question?
{-# LANGUAGE TemplateHaskell #-}
module Bla where
import Polysemy
data E1 :: Effect where
E1_unit :: E1 m ()
E1_rec :: m a -> E1 m a
makeSem ''E1
data E2 :: Effect where
E2_unit :: E2 m ()
E2_rec :: m a -> E2 m a
makeSem ''E2
bla :: Member E1 r => Member E2 r => Sem r ()
bla = do
e1_rec $ do
e1_unit
e2_unit
e2_rec $ do
e1_unit
e2_unit
e1_rec $ do
e1_unit
e2_unit
Of course, this doesn't restrict the do
block to only contain E1
and E2
in it, which might be an issue for you?
@googleson78 thanks! I had briefly tried it, but backed out as I couldn't figure out how could I use the m
in interpretation (also using interpretH
, and just now getting it to work with pureT
is scary..).
In the "hard part" below I'd essentially like to run all the effects to the end using the current state, but modify the writer before writing it in to the "main interpretation":
-- | E1 is meant to be interpreted to these effects:
type E1_Base = '[State Int, Writer String]
-- | Interpret E1 in terms of E1_Base
e1ToBase :: forall r . (Members E1_Base r) => InterpreterFor E1 r
e1ToBase = interpretH $ \case
E1_unit -> do
modify @Int (+1)
tell @String "this"
pureT ()
E1_rec m -> do
-- the hard part:
-- state0 <- get @Int
-- let
-- (writer, (state1, a)) = runWriter $ runState state0 $ ..?.. $ m
-- modifiedWriter = "begin " <> writer <> " end"
-- put @Int state1
-- tell @String modifiedWriter
-- return a
return undefined
Is something like the following possible in polysemy where given the effects
one could write something like this:
I.e I arbitrarily mix different effects under both effects'
_rec
variants and the effect stack is same on each "level".My actual use case is that I have DSLs for generating css and javascript both of which have their separate effects/GADTs and interpreters, and am wondering if I could re-use them without writing a sum GADT.