Pre/post processing in Effect handler #299
Answered
by
emlautarom1
emlautarom1
asked this question in
Q&A
-
Assume that I have the following Effect: data Severity = Info | Error | Fatal
deriving (Show, Eq, Ord, Bounded)
data Logger e :: Effect where
Log :: Severity -> String -> (Logger e) m ()
type instance DispatchOf (Logger e) = Dynamic
log :: (Logger e :> es) => Severity -> String -> Eff es ()
log severity message = send $ Log severity message I would like to write an interpreter that:
(this is just an example use case, not something real) As a skeleton I have something like: runFileLogger :: (IOE :> es) => FilePath -> Eff (Logger e : es) a -> Eff es a
runFileLogger path = do
-- Use `withFile` or similar to get a `Handle`. The file should be opened once.
-- withFile path WriteMode $ \handle ->
-- Store some kind of counter variable (`IORef` maybe?)
-- counter <- ???
interpret $ \env op -> case op of
Log severity message -> do
-- update the counter
liftIO $ hPutStrLn handle message
-- if the counter reaches 10, call `hFlush handle`
|
Beta Was this translation helpful? Give feedback.
Answered by
emlautarom1
Feb 3, 2025
Replies: 1 comment 4 replies
-
After some trial and error I ended up with: runFileLogger :: (IOE :> es) => FilePath -> Eff (Logger e : es) a -> Eff es a
runFileLogger path logger = do
counter <- liftIO $ newIORef (0 :: Int)
withFile path WriteMode $ \handle -> do
interpretWith logger $ \_ -> \case
Log severity message -> liftIO $ do
atomicModifyIORef' counter $ \c -> (c + 1, ())
hPutStrLn handle message
whenM ((== 10) <$> readIORef counter) $ do
hFlush handle
atomicModifyIORef' counter $ const (0, ()) This is pretty much what I was looking for but there are a couple of issues:
These are very small issues but I would like to know if there is any way to remove them. |
Beta Was this translation helpful? Give feedback.
4 replies
Answer selected by
emlautarom1
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
After some trial and error I ended up with:
This is pretty much what I was looking for but there are a couple of issues:
unliftio
as a dependency to workaround theIO
limitation ofSystem.IO.w…