我是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
实现了一系列功能(length
,foldr
等)。现在我想搬到树上!
我的树数据结构:
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 []])
答案 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)
与相同提示相对应的基类为Foldable
和Functor
。基数为Foldable
的所有内容都已为Functor
;能够独立于treeMap
定义treeFold
是很自然的。