在树上映射

时间:2015-10-01 23:03:53

标签: haskell dictionary tree fold

我是Haskell的新手,在实践中,我使用declare l_exists integer; begin begin select 1 into l_exists from dual where exists( select 1 from items where id_referencia = :P2_REFERENCIA ); exception when no_data_found then l_exists := 0; end; if( l_exists = 1 ) then return true; else return false; end if; end; map实现了一系列功能(lengthfoldr等)。现在我想搬到树上!

我的树数据结构:

foldl

我编写了一个Haskell函数来折叠树:

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

其中treeFold :: (b->a->b) -> b -> Tree a -> b treeFold f s (Node a []) = f s a treeFold f s (Node a xs) = foldl f (f s a) (dFSList xs) 是树中所有节点的列表。所以做一些事情:

dFSList

返回6.酷。

现在我想编写一个Haskell函数来映射树,但我想使用我的treeFold (+) 0 (Node 1 [Node 2 [], Node 3 []]) 函数来完成它。以下是我到目前为止的情况:

treeFold

如何完成treeMap f (Node a []) = (Node (f a) []) treeMap f (Node a (x:xs)) = (Node (f a) (a list involving foldTree somehow??)) 功能?我希望能够做到

treeMap

它应该返回

treeMap (+1) (Node 1 [Node 2 [], Node 3 []])

2 个答案:

答案 0 :(得分:6)

分解树木的方法通常是不同种类的折叠(对于我不知道的某些类别理论原因,通常称为变形)。你有data Tree a = Node a [Tree a],所以要把它分开,你做

cat :: (a -> [b] -> b) -> Tree a -> b
cat f (Node root children) = f root (map (cat f) children)

Hokay?所以现在(使用标准Functor类而不是专门的treeMap),

instance Functor Tree where
  fmap f = cat (Node . f)

您也可以像这样编写线性折叠。你的treeFold让我感到困惑,但你可以写一下,例如,

instance Foldable Tree where
  foldMap f = cat go where
    go root children = f root `mappend` fold children

更强大,

instance Traversable Tree where
  traverse f = cat go where
    go root children = Node <$> f root <*> sequenceA children

答案 1 :(得分:5)

您不需要treeFold来编写类似treeMap的内容。

treeMap f (Node a xs) = Node (f a) (map (treeMap f) xs)

与相同提示相对应的基类为FoldableFunctor。基数为Foldable的所有内容都已为Functor;能够独立于treeMap定义treeFold是很自然的。