所以我有,我要崩潰了其中節點是類型如何摺疊特殊情況下的構造函數?
data Node = Node1 Node | Node2 Node Node | ... deriving Data
的除少數特殊情況下的樹。我想做的事的
collapse SPECIALCASE1 = ...
collapse SPECIALCASE2 = ...
...
collapse node = foldl (++) $ gmapQ validate node
,所有的特殊情況下產生的結果,確定最後的情況下,只需遞歸崩潰的名單東西線;但是這不起作用,因爲作爲gmapQ的第一個參數的函數必須是forall d. Data d => d -> u
類型的函數,而不是Node -> u
,而據我所知,它僅限於使用在Data
類型上運行的函數。
是否有任何方式強迫問題的值是正確的類型,或另一個更寬鬆的地圖功能?
額外的信息:
以上爲collapse
被命名爲validate
,是在抽象語法樹遍歷和發現綁定的變量(一個非常簡單的語言)該特殊情況中描述的功能的實際代碼這樣
validate _ (Nr _) = []
validate env (Let var val expr) = validate env val ++ validate (var:env) expr
validate env (Var var) = if elem var env then [] else [var]
基本上是字面數字沒有在他們的變量,讓表達式的規則處理綁定一個變量,變量需要的,如果綁定或者不進行檢查。這個玩具語言中的其他構造只是數字和變量的組合(例如求和,乘法等),因此當我檢查未綁定的變量時,我只需要遍歷它們的子樹併合並結果;因而是gmapQ
。
額外信息2:
上述代替Node
例子的實際數據類型的形式
data Ast = Nr Int
| Sum Ast Ast
| Mul Ast Ast
| Min Ast
| If Ast Ast Ast
| Let String Ast Ast
| Var String
deriving (Show, Eq, Data)
當你知道類型時,你需要所有這些花哨的通用東西嗎?爲什麼不把它精確地寫入(模式匹配),並且可能完全跳過'gmapQ'? – dfeuer
大多數'NodeX'構造函數都有這種重複模式的子節點,我在上面展示,並且爲它們中的每一個編寫模式都是非常多餘的;這是我想要避免的。 –
好吧,沒有什麼能夠阻止你通過將「手動」調度到一個或多個通用幫助程序來組合方法。 – dfeuer