如何根据哪个monad位于变换器堆栈的基础上编写一个行为不同的函数

时间:2015-06-04 16:47:16

标签: haskell

(在这一点上,这更像是一个谜题,我想知道如何解决,而不是我希望在实践中使用的解决方案)

我尝试使用以下规范编写函数runDebug:其参数的类型为IO ();其返回类型为(Monad m) => m ();取决于m,它表现为两种不同的方式之一;如果MonadIO m,则为runDebug = liftIO,否则为runDebug = const (return ())

我尝试的方法依赖于类型类

class MonadDebug m where
  runDebug :: IO () -> m ()

我已尝试使用MonadBase,我尝试将MonadIO用于重叠实例,但所有这些都遇到了歧义问题。

我想我可以通过为每个变压器编写实例来获得一些有效的东西,但我一直希望避免这种情况。

2 个答案:

答案 0 :(得分:6)

为每个变压器和您有兴趣支持的每个基础monad写入MonadDebug的实例。

答案 1 :(得分:0)

当然,只要我发布到SO,我就会弄清楚如何得到我想要的东西。

据我所知,以下代码解决了我的问题:

class (Monad m) => MonadDebug m where
  runDebug :: IO () -> m ()

instance MonadDebug Identity where
  runDebug _ = return ()

instance MonadDebug IO where
  runDebug m = m

instance (Monad (t m), MonadTrans t, MonadDebug m) => MonadDebug (t m) where
  runDebug m = lift $ runDebug m