如何高效共享递归数据结构?

时间:2015-07-22 07:09:02

标签: performance haskell

考虑一个递归的分支数据结构:

data Tree a = Node (Tree a) (Tree a) | Leaf a
    deriving (Show)

可以构造一个具有许多相同分支的Tree,这似乎可以有效地处理(至少在GHC中) - 例如,通过:

maketree :: Integer -> a -> Tree a
maketree 1 value = Leaf value
maketree depth value = let child = maketree (depth-1) value in Node child child

maketree 32 "Hello"将返回一个Tree String概念上包含4294967295个节点 - 但实际上只有32个节点将存储在内存中,而maketree的主体只会被评估32次。

但是,假设我们实际上尝试以某种方式使用整个树 - 例如,计算节点数:

count :: Tree a -> Integer
count n = case n of
    Leaf _   -> 1
    Node a b -> 1 + count a + count b

count (maketree 32 "Hello")将(正确)评估为4294967295,但它会通过评估count 4294967295次的正文来实现。

但是因为实际上只有32个节点对象"存储在内存中,并且由于count是纯的(作为Haskell函数),因此应该可以为每个节点对象缓存结果,并且仅评估count 32次。

有没有办法让GHC(或任何Haskell实现)这样做?

0 个答案:

没有答案