简体   繁体   English

如何推理Haskell中的空间复杂性

[英]How to reason about space complexity in Haskell

I'm trying to find a formal way to think about the space complexity in haskell. 我正试图找到一种正式的方式来考虑haskell中的空间复杂性。 I have found this article about the Graph Reduction ( GR ) technique which seems to me as a way to go. 我发现这篇关于图形缩减( GR )技术的文章在我看来是一种方法。 But I'm having problems applying it in some cases. 但是我在某些情况下应用它时遇到了问题。 Consider the following example: 请考虑以下示例:

Say we have a binary tree: 假设我们有一个二叉树:

data Tree = Node [Tree] | Leaf [Int]

makeTree :: Int -> Tree
makeTree 0 = Leaf [0..99]
makeTree n = Node [ makeTree (n - 1)
                  , makeTree (n - 1) ]

and two functions that traverse the tree, one ( count1 ) which streams nicely and the the other one ( count2 ) that creates the whole tree in memory at once; 和两个遍历树的函数,一个( count1流畅地流动,另一个( count2 )一次在内存中创建整个树; according to the profiler. 根据剖析器。

count1 :: Tree -> Int
count1 (Node xs) = 1 + sum (map count1 xs)
count1 (Leaf xs) = length xs

-- The r parameter should point to the root node to act as a retainer.
count2 :: Tree -> Tree -> Int
count2 r (Node xs) = 1 + sum (map (count2 r) xs)
count2 r (Leaf xs) = length xs

I think I understand how it works in the case of count1 , here is what I think happens in terms of graph reduction: 我想我理解它在count1的情况下是如何工作的,这是我认为在图形缩减方面发生的事情:

count1 $ makeTree 2
=> 1 + sum $ map count1 xs
=> 1 + sum $ count1 x1 : map count1 xs
=> 1 + count1 x1                                + (sum $ map count1 xs)
=> 1 + (1 + sum $ map count1 x1)                + (sum $ map count1 xs)
=> 1 + (1 + sum $ (count1 x11) : map count1 x1) + (sum $ map count1 xs)
=> 1 + (1 + count1 x11 + sum $ map count1 x1)   + (sum $ map count1 xs)
=> 1 + (1 + count1 x11 + sum $ map count1 x1)   + (sum $ map count1 xs)
=> 1 + (1 + 100 + sum $ map count1 x1)          + (sum $ map count1 xs)
=> 1 + (1 + 100 + count x12)                    + (sum $ map count1 xs)
=> 1 + (1 + 100 + 100)                          + (sum $ map count1 xs)
=> 202                                          + (sum $ map count1 xs)
=> ...

I think it's clear from the sequence that it runs in constant space, but what changes in case of the count2 ? 我认为从序列中可以清楚地知道它在恒定的空间中运行,但是在count2的情况下会发生什么变化?

I understand smart pointers in other languages so I vaguely understand that the extra r parameter in count2 function somehow keeps nodes of the tree from beeing destroyed, but I would like to know the exact mechanism, or at least a formal one which I could use in other cases as well. 我理解其他语言的智能指针,所以我模糊地理解count2函数中的额外r参数以某种方式保持树的节点不被破坏,但我想知道确切的机制,或者至少是我可以使用的正式机制其他情况也是如此。

Thanks for looking. 谢谢你的期待。

You could use Adam Bakewell's space semantics, 你可以使用Adam Bakewell的空间语义,

Haskell currently lacks a standard operational semantics. Haskell目前缺乏标准的操作语义。 We argue that such a semantics should be provided to enable reasoning about operational properties of programs, to ensure that implementations guarantee certain space and time behaviour and to help determine the source of space faults. 我们认为应该提供这样的语义,以便能够推断程序的操作属性,确保实现保证某些空间和时间行为,并帮助确定空间故障的来源。 We present a small-step deterministic semantics for the sequential evaluation of Core Haskell programs and show that it is an accurate model of asymptotic space and time usage. 我们为Core Haskell程序的顺序评估提供了一个小步骤确定性语义,并表明它是渐近空间和时间使用的精确模型。 The semantics is a formalisation of a graphical notation so it provides a useful mental model as well as a precise mathematical notation. 语义是图形符号的形式化,因此它提供了有用的心理模型以及精确的数学符号。 We discuss its implications for education, programming and implementation. 我们讨论它对教育,规划和实施的影响。 The basic semantics is extended with a monadic IO mechanism so that all the space under the control of an implementation is included. 使用monadic IO机制扩展基本语义,以便包含实现控制下的所有空间。

Or work from the Coq specification of the STG machine . 或者使用STG机器的Coq规范

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM