我有一个以下 monad 变压器堆栈,包括 monad-logger 变压器,并且我希望能够通过参数关闭日志记录。
我可以看到,有 NoLoggingT
类型,但我不知道如何使其工作。
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)
如何关闭本例中的日志记录?
我可以看到函数 filterLogger
在停用日志记录的情况下可能始终返回 false,但是有 runNoLoggingT
的解决方案吗?
最佳答案
您的 MyApp 类型太具体:它始终包含 LoggingT,因此它始终在启用日志记录的情况下运行。您可以给它一个类型参数,并使用 LoggingT 或 NoLoggingT 实例化该类型参数:
newtype MyApp log a = MyApp
{ runApp :: StateT Direction (log IO) a
}
deriving (Functor, Applicative, Monad, MonadIO, MonadState Direction, MonadLogger)
然后 MyApp LoggingT
记录日志,而 MyApp NoLoggingT
不记录日志。不关心使用哪个(可能是您的程序的大部分)的客户将不指定该类型变量:
doSomething :: MonadLogger (log IO) => MyApp log Int
doSomething = undefined
它们可以调用日志函数,这些函数要么执行某些操作,要么不执行任何操作,具体取决于运行应用程序时在顶层使用的新类型。
关于haskell - 无法将 LoggingT 与 NoLoggingT 匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70689239/