【问题标题】:haskell fold rose tree paths哈斯克尔折叠玫瑰树路径
【发布时间】:2014-07-24 18:58:27
【问题描述】:

假设我们有一棵树...

data Tree a = Node a [Tree a] deriving (Show)

那棵树有一些节点

t = Node 1 [Node 2 [Node 3 []], Node 4 [], Node 5 [Node 6 []]]

以下函数将collect树中的路径。

paths :: Tree a -> [[a]]
paths (Node n []) = [[n]]
paths (Node n ns) = map ((:) n . concat . paths) ns

像这样:

*Main> paths t
[[1,2,3],[1,4],[1,5,6]]

但是现在我们怎么能fold 这些路径呢?显然我们可以做到这一点。找到路径后折叠。

wastefullFold :: (a -> b -> b) -> b -> Tree a -> [b]
wastefullFold f z (Node n ns) = map (foldr f z) $ paths (Node n ns)

*main> wastefullFold (+) 0 t
[6,5,12]

我能做到的最接近的是:

foldTreePaths :: (a -> [b] -> [b]) -> [b] -> Tree a -> [[b]]
foldTreePaths f z (Node n []) = [f n z]
foldTreePaths f z (Node n ns) = map (f n . concat . foldTreePaths f z) ns

*Main> foldTreePaths (:) [] a
[1,2,3],[1,4],[1,5,6]]

*Main> foldTreePaths ((:) . (+ 1)) [] a
[[2,3,4],[2,5],[2,6,7]]

但我觉得下面应该有比这更干净的东西

*Main> foldTreePaths (\node base -> [node + sum base]) [0] a
[[6],[5],[12]]

基本上我不知道怎么写foldTreePaths,签名如下:

foldTreePaths :: (a -> b -> b) -> b -> Tree a -> [b]

【问题讨论】:

    标签: haskell tree fold


    【解决方案1】:

    我认为这很容易理解:

    foldRose f z (Node x []) = [f x z]
    foldRose f z (Node x ns) = [f x y | n <- ns, y <- foldRose f z n]
    
    > foldRose (:) [] t
    [[1,2,3],[1,4],[1,5,6]]
    > foldRose (+) 0 t
    [6,5,12]
    

    【讨论】:

    • 出于某种原因,我认为你不能写出这样的理解。大 + 1
    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-12
    • 2018-08-29
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多