Couldn't match LoggingT with NoLoggingT

Viewed 154

I have a following monad transformer stack including the monad-logger transformer and I want to be able to turn off logging by a parameter.

I can see, there is the NoLoggingT type but I don't know how to make it work.

newtype MyApp a = MyApp
  { runApp :: StateT Direction (LoggingT IO) a
  }
  deriving (Functor, Applicative, Monad, MonadIO, MonadState Direction, MonadLogger)

runMyApp :: Params -> MyApp a -> Direction -> IO (a, Direction)
runMyApp (Params _ True) app st = runFileLoggingT "log.log" (runStateT (runApp app) st)
runMyApp (Params _ False) app st = runNoLoggingT (runStateT (runApp app) st)

How to turn off logging in this example?

I can see the function filterLogger that could return always false in case of deactivating the logging but is there any solution with the runNoLoggingT?

1 Answers

Your MyApp type is too concrete: it always includes LoggingT, so it always runs with logging enabled. You could give it a type parameter, and instantiate that type parameter either with LoggingT or NoLoggingT:

newtype MyApp log a = MyApp
  { runApp :: StateT Direction (log IO) a
  }
  deriving (Functor, Applicative, Monad, MonadIO, MonadState Direction, MonadLogger)

Then MyApp LoggingT logs, and MyApp NoLoggingT doesn't log. A client who doesn't care which is used (most of your program, probably) will leave that type variable unspecified:

doSomething :: MonadLogger (log IO) => MyApp log Int
doSomething = undefined

They can call log functions, which will either do something or do nothing, depending on which newtype you use at the top level when running the app.

Related