我有一些代码目前使用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”的方法调用它它
答案 0 :(得分:17)
如果您想要IORef
和STRef
的统一界面,您是否看过the stateref
package?它具有“可变数据引用”的类型类,以可读,可写等分隔,包含IORef
和STRef
的实例,以及TVar
,{{1 },MVar
等
答案 1 :(得分:10)
您是否考虑过Debug.Trace.trace?