Suppose I catch key presses and manipulate a code buffer accordingly:
let
bCode = accumB emptyCode eModifications
eCodeChanges <- changes bCode
I would like to create another behaviour bEval
bEval = accumB freshEnv (magic eCodeChanges)
which maps any state of code to its evaluation (triggered only when something really changes).
However, evaluation happens in a monad Interpreter
(think hint
from hackage). Can I actually define such a behaviour bEval
? I guess I could just drag Interpreter String
as the state in my behaviour, accumulating with currentAccumState >>= eval nextEvent
, but where would I runInterpreter
to actually force the evaluation?
Edit: Important thing is that the actions are not merely IO ()
but are supposed to modify some state. Consider for example clearing a buffer/reseting counter/moving around a zipper.
My idea was along the lines:
f :: a -> Maybe (b -> IO b)
mapJustIO :: (a -> Maybe (b -> IO b)) -> Event t a -> Event t (b -> IO b)
mapJustIO f e = filterJust $ f <$> e
accumIO :: a -> Event t (a -> IO a) -> Behaviour t (IO a)
accumIO z e = fold (>>=) (return z) e
I don't see why there could not be something like this. However, I don't see how to get rid of that IO
in the behaviour either :).
Why aren't IO
occurrences in reactive-banana
actually only MonadIO
?