haskell - 无法将 LoggingT 与 NoLoggingT 匹配

标签 haskell logging monad-transformers

我有一个以下 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/

相关文章:

Haskell 类型类层次结构

c# - 重复代码位的设计模式/C#技巧

logging - 软件制造商/产品/版本的 URN/URI

f# - 将 "bind"与异步函数一起使用

design-patterns - 有人在野外遇到过 Monad Transformer 吗?

haskell - Haskell 中数据类型的混淆

haskell - 有没有一种方法可以使用 Derive 和 Template Haskell 或其他方式派生 Vinyl 记录类型的二进制实例

haskell - 如何实现无点交互?

java.util.logging.Logger 与根 Logger 具有不同的级别

haskell - 如何使用 StateT、ContT 和 ReaderT 创建 monad?