我尝试通过一个树来概括所有路径,该树将从根到最低子节点的每个级别扩展1到10倍。 我的函数遍历所有孩子,但我遇到的问题是,当我尝试创建节点列表并在列表中执行此列表时,我成为列表列表的List ...列表。 我认为我的问题是组合步骤我尝试制作模式匹配方法,但是当它成为列表列表时应该比较列表的方法,并且应该创建新列表并比较它们,如果它只是一种方式(满足列表)使用节点而不是带列表的列表)不起作用。
答案 0 :(得分:5)
summarize :: Tree a -> [[a]]
summarize Leaf = [[]]
summarize (Node a t1 t2) = do
t <- [t1, t2]
map (a:) (summarize t)
编辑:请注意,上面假设Tree
的以下定义:
data Tree a = Leaf | Node a (Tree a) (Tree a)
编辑#2:此版本的代码可能更清晰:
summarize :: Tree a -> [[a]]
summarize Leaf = [[]]
summarize (Node a t1 t2) = do
t <- [t1, t2]
summary <- summarize t
return (a:summary)
这个版本有一个很好的属性,它可以写成列表理解:
summarize (Node a t1 t2) = [a:summary | t <- [t1, t2], summary <- summarize t]
答案 1 :(得分:1)
树可以表示为list-monadic-list(列表中有几个选项,用于在每个点恢复它)。然后,你想要的只是这个monadic列表的折叠。
import Control.Monad.Trans.List.Funcs (repeatM) -- cabal install List
import qualified Data.List.Class as L
exampleTree = L.take 3 (repeatM [0, 1])
查看所有路径:
ghci> L.toList exampleTree
[[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
总结所有路径:
ghci> L.foldlL (+) 0 exampleTree
[0,1,1,2,1,2,2,3]
对于树的这种表示,ListTree包为表示为ListT []
s的树上的树操作(例如DFS / BFS迭代)提供组合器。