如何将MonadLogger添加到我的免费monad变换器堆栈?

时间:2016-01-27 05:39:54

标签: haskell logging monad-transformers free-monad

我已经问过这个问题here,但我想我也会尝试这样做。

如何将MonadLogger添加到此免费monad变换器堆栈?

newtype Craft a = Craft { unCraft :: ReaderT CraftEnv (FreeT CraftDSL IO) a }
  deriving ( Functor, Monad, MonadIO, Applicative
           , MonadReader CraftEnv, MonadFree CraftDSL, MonadThrow)

我能够毫无问题地添加MonadThrow;我希望添加MonadLogger同样容易。

我尝试添加它并收到此错误:

No instance for (MonadLogger (FreeT CraftDSL IO))
  arising from the 'deriving' clause of a data type declaration

如果我定义一个实例:

instance MonadLogger (FreeT CraftDSL IO) where
  monadLoggerLog a b c d = Trans.lift $ monadLoggerLog a b c d

我收到此错误:

Could not deduce (MonadLogger IO)
  arising from a use of ‘monadLoggerLog’

Here是我正在编写的基本示例的链接。

2 个答案:

答案 0 :(得分:2)

FreeT添加到堆栈的基础可立即工作,但从

判断
  

没有实例(MonadLogger(FreeT CraftDSL IO))     来自数据类型声明的“派生”子句

你想记录你的DSL do-blocks中的东西。为此,我们需要MonadLogger instance (MonadLogger m, Functor f) => MonadLogger (FreeT f m) where monadLoggerLog loc source level msg = lift $ monadLoggerLog loc source level msg 的实例:

LoggingT

感谢MonadLogger已成为(MonadLogger m) => MonadLogger (FreeT f m)的实例,Craft约束适用于您的{{1}}类型。

此代码为我编译,但由于您没有提供最小的测试用例,我不确定它是否真的有效。

答案 1 :(得分:1)

LoggingT添加到变压器堆栈中,即

newtype Craft a = Craft { unCraft :: ReaderT CraftEnv (LoggingT (FreeT CraftDSL IO)) a }
  deriving ( Functor, Monad, MonadIO, Applicative
           , MonadReader CraftEnv, MonadFree CraftDSL, MonadThrow, MonadLogger)

或者如果您需要登录DSL的解释:

newtype Craft a = Craft { unCraft :: ReaderT CraftEnv (FreeT CraftDSL (LoggingT IO)) a }

如果缺少实例,则需要手动编写,因为freemonad-logger包不会为其他变换器提供实例。