(在这一点上,这更像是一个谜题,我想知道如何解决,而不是我希望在实践中使用的解决方案)
我尝试使用以下规范编写函数runDebug
:其参数的类型为IO ()
;其返回类型为(Monad m) => m ()
;取决于m
,它表现为两种不同的方式之一;如果MonadIO m
,则为runDebug = liftIO
,否则为runDebug = const (return ())
。
我尝试的方法依赖于类型类
class MonadDebug m where
runDebug :: IO () -> m ()
我已尝试使用MonadBase
,我尝试将MonadIO
用于重叠实例,但所有这些都遇到了歧义问题。
我想我可以通过为每个变压器编写实例来获得一些有效的东西,但我一直希望避免这种情况。
答案 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