Haskell - 双重人格IO / ST monad?

时间:2011-07-26 22:24:20

标签: haskell monads io-monad st-monad

我有一些代码目前使用ST monad进行评估。我不喜欢将IO放在任何地方,因为runST方法产生纯粹的结果,并且表明这样的结果可以安全地调用(而不是unsafePerformIO)。但是,由于我的一些代码变得更长,我确实希望将调试打印语句放在。

是否有任何类提供双重个性monad [或类型类机制],可以是ST或IO(取决于其类型或“isDebug”标志)?我记得SPJ在他的“Fun with Type Functions”论文中引入了一个“Mutation”类,它使用关联类型将IO与IORef和ST关联到STRef。这样的包存在某个地方吗?

编辑/解决方案

非常感谢[第n次],C.A。麦肯!使用该解决方案,我能够为支持pdebug函数的monad引入一个额外的类。 ST monad将忽略这些调用,而IO将运行putStrLn

class DebugMonad m where
    pdebug :: String -> m ()

instance DebugMonad (ST s) where
    pdebug _ = return ()

instance DebugMonad IO where
    pdebug = putStrLn

test initV = do
    v <- newRef initV
    modifyRef v (+1)
    pdebug "debug"
    readRef v
testR v = runST $ test v

这在ghci中有一个非常幸运的结果。由于默认情况下表达式是IO类型,因此运行类似“test 3”的操作将导致IO monad运行,因此您可以轻松地调试它,然后在您真正想要运行时使用类似“testR”的方法调用它它

2 个答案:

答案 0 :(得分:17)

如果您想要IORefSTRef的统一界面,您是否看过the stateref package?它具有“可变数据引用”的类型类,以可读,可写等分隔,包含IORefSTRef的实例,以及TVar,{{1 },MVar

答案 1 :(得分:10)

您是否考虑过Debug.Trace.trace?

http://www.haskell.org/haskellwiki/Debugging