[Haskell-cafe] Writer + log each computation to stdout

Tillmann Rendel rendel at informatik.uni-marburg.de
Tue Nov 26 02:34:47 UTC 2013


Hi,

Bryan Vicknair wrote:
> I have a bunch of little database IO functions.  Each does something to the
> database, and returns a log string describing what it did, and possibly a
> meaningful result from the database.
>
>    query  :: IO (String, a)
>    update :: a -> IO (String, ())
>
> ...and a few functions that orchestrate all the little functions into doing
> useful work.
>
>    syncWeek :: Week -> IO ()
>    syncAll  : : IO ()
>
> I don't want the individual functions to know what is done with the log string
> describing what they did.  Top-level orchestrating functions should make that
> decision, which can be one of:
>
> 1) Collect and print all to a log once all computations are done.
> 2) Print to stdout *as each computation is run*.
> 3) Ignore them.

Instead of using an existing monad transformer, I would consider to 
write my own set of logging monad transformers. This could give you this 
interface:

   class MonadLog m where
     log :: String -> m ()

   query :: (MonadIO m, MonadLog m) => m a
   update :: (MonadIO m, MonadLog m) => a -> m ()

And then you can provide different implementations for MonadLog:

   newtype IgnoreLogT m a = IgnoreLogT { runIgnoreLogT :: m a }

   instance MonadLog (IgnoreLogT m) where
     log _ = return ()


   newtype ConsoleLogT m a = ConsoleLogT { runConsoleLogT :: m a }

   instance MonadIO m => MonadLog (ConsoleLogT m) where
     log msg = liftIO (putStrLn msg)


   newtype StringLogT m a =
     StringLogT { runStringLogT :: WriterT String m a }

   instance MonadLog (StringLogT m) where
     log msg = StringLogT $ tell msg

Tillmann


More information about the Haskell-Cafe mailing list