Haskell - 双重人格IO/ST monad?

gat*_*ado 18 monads haskell io-monad st-monad

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

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

编辑/解决方案

非常感谢[第n次],CA McCann!使用该解决方案,我能够为支持pdebug函数的monad引入一个额外的类.该ST单子会忽略这些呼叫,而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
Run Code Online (Sandbox Code Playgroud)

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

C. *_*ann 17

如果你想要一个统一的接口IORefSTRef,让你看着stateref?它具有,用于分离可读,可写,等等."至可变数据的引用"型的类,与用于实例IORefSTRef,以及像的东西TVar,MVar,ForeignPtr等.


Jer*_*man 10

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

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