我有這樣的語言AST有沒有像cata的東西,但你可以匹配內部結構?
data ExprF r = Const Int
| Var String
| Lambda String r
| EList [r]
| Apply r r
deriving (Show, Eq, Ord, Functor, Foldable)
我想將它轉換爲字符串
toString = cata $ \case
Const x -> show x
Var x -> x
EList x -> unwords x
Lambda x y -> unwords [x, "=>", y]
Apply x y -> unwords [x, "(", y, ")"]
但是,當拉姆達在Apply
使用我所需要的括號
(x => x)(1)
,但我不能匹配cata的內部結構
toString :: Fix ExprF -> String
toString = cata $ \case
Const x -> show x
Var x -> x
Lambda x y -> unwords [x, "=>", y]
Apply (Lambda{}) y -> unwords ["(", x, ")", "(", y, ")"]
Apply x y -> unwords [x, "(", y, ")"]
有沒有比para
更好的解決方案?
toString2 :: Fix ExprF -> String
toString2 = para $ \case
Const x -> show x
Var x -> x
Lambda x (_,y) -> unwords [x, "=>", y]
EList x -> unwords (snd <$> x)
Apply ((Fix Lambda {}),x) (_,y) -> unwords ["(", x, ")", "(", y, ")"]
Apply (_,x) (_,y) -> unwords [x, "(", y, ")"]
它看起來更醜。即使它只需要在一個地方,我需要刪除fst元組參數,我想它會變慢。
在一般情況下,您可以像'showsPrec'中那樣採用優先參數。儘管如此,帕拉對我來說不算太糟糕。 – chi
你能詳細說明一下嗎?我不知道我可以把這個論點放在哪裏。在這種情況下,「para」是可以的,但是當ast更大時,它只是太多的噪音 – ais
@ais我現在沒有時間寫完整答案,但是可以將'Bool'傳遞給遞歸通過摺疊到函數'Bool - > a'來調用。 [Kiselyov's tagless final notes](http://okmij.org/ftp/tagless-final/course/lecture.pdf)觸及它。 –