8
可以將免費單片機翻譯爲任何其他單片機,但給定類型爲Free f x
的值時,我想打印整棵樹,而不是將生成的AST的每個節點映射到另一單片機中的某個其他節點。打印免費單片機
加布裏埃爾岡薩雷斯uses值直接
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"
可以抽象出來作爲
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
這是容易的,如果我們有像(使用Choice x = Choice x x
作爲仿)
showChoice :: forall x. (x -> String) -> Choice x -> String
showChoice show (Choice a b) = "Choice (" ++ show a ++ "," ++ show b ++ ")"
但是,這似乎相當複雜用於簡單操作... 還有什麼其他方法可以從f x -> b
到Free f x -> b
?
啊,這很好!謝謝。現在我發現很明顯,人們必須尋找將'f'的代數翻譯爲'Free f'的代數。 – nicolas
我喜歡你的'iter''。我試圖最近找到一些服務於這個普通用途的東西(感覺自己肯定有一個),但某種方式未能擊中正確的類型。 – dfeuer
這可能是有價值的基準對'iter'f g =去哪裏......。有些測量表明,當至少有兩個參數在遞歸中保持不變時,這往往是好的。 – dfeuer