現在、評価にSTモナドを使用しているコードがいくつかあります。runST
メソッドが純粋な結果を生成し、そのような結果を安全に呼び出すことができることを示しているため、IOをどこにでも配置しないのが好きです(に対してunsafePerformIO
)。ただし、一部のコードが長くなっているため、デバッグ用のprintステートメントをに入れたいと思います。
STまたはIO(タイプまたは「isDebug」フラグに応じて)のデュアルパーソナリティモナド[またはタイプクラスの機械]を提供するクラスはありますか?SPJが彼の「FunwithTypeFunctions」の論文で「Mutation」クラスを紹介したことを思い出します。このクラスでは、結合型を使用してIOをIORefに、STをSTRefに関連付けました。そのようなものはどこかにパッケージとして存在しますか?
編集/解決策
どうもありがとうございました[n回目]、CA McCann!pdebug
そのソリューションを使用して、関数をサポートするモナド用の追加のクラスを導入することができました。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
これはghciに非常に幸運な結果をもたらします。式はデフォルトでIOタイプであると想定されているため、「test 3」のようなものを実行すると、IOモナドが実行されるため、簡単にデバッグして、実際に実行するときに「testR」のようなもので呼び出すことができます。それ。