Skip to content

Pre/post processing in Effect handler #297

@emlautarom1

Description

@emlautarom1

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:

  1. Takes a FilePath as argument
  2. Opens the file in WriteMode once
  3. Every 10 writes it flushes the file handle

(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`
  1. The signature runFileLogger :: (IOE :> es) => FilePath -> Eff (Logger e : es) a -> Eff es a is what I would like to have.
  2. Notice how certain operations should be executed "before" the interpret call
  3. We're dealing with the withXXX pattern since we want to do something before & after interpreting the Effect: open the file and closing it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions