8
無料のモナドを他のモナドに変換できますが、タイプがFree f x
の場合、生成されたASTのすべてのノードを別のモナドの他のノードにマップしないでツリー全体を印刷します。フリーモナドの印刷
ガブリエル・ゴンザレスuses値我々は(ファンクタとしてChoice x = Choice x x
を使用して)のような多型の機能を持っている場合は呼び出すことは容易である
showF :: (x -> b) -> ((Free f x -> b) -> f (Free f x) -> b) -> Free f x -> b
showF backLiftValue backLiftF = fix (showFU backLiftValue backLiftF)
where
showFU :: (x -> b) -> ((Free f x -> b) -> f (Free f x) -> b) -> (Free f x -> b) -> Free f x -> b
showFU backLiftValue backLiftF next = go . runIdentity . runFreeT where
go (FreeF c) = backLiftF next c
go (Pure x) = backLiftValue x
として抽象化することができ、直接
showProgram :: (Show a, Show r) => Free (Toy a) r -> String
showProgram (Free (Output a x)) =
"output " ++ show a ++ "\n" ++ showProgram x
showProgram (Free (Bell x)) =
"bell\n" ++ showProgram x
showProgram (Free Done) =
"done\n"
showProgram (Pure r) =
"return " ++ show r ++ "\n"
showChoice :: forall x. (x -> String) -> Choice x -> String
showChoice show (Choice a b) = "Choice (" ++ show a ++ "," ++ show b ++ ")"
しかし、それはかなり複雑です簡単な操作のためにated ... f x -> b
からFree f x -> b
に行く他の方法はありますか?
ああ、それはよかったです!ありがとうございました。今私は 'f 'の代数を' f'の代数に変換することを見なければならないことは明らかです。 – nicolas
私はあなたの 'iter'を好きです。私は最近、その一般的な目的に役立つものを見つけようとしましたが(あるものと確信していると感じていますが)何らかの形で正しいタイプのヒットに失敗しました。 – dfeuer
これを 'iter 'fg = go where ...'に対してベンチマークする価値があります。いくつかの測定は、少なくとも2つの引数が再帰を介して一定のままであるときにこれが良い傾向にあることを示しています。 – dfeuer