以下两个 lambda 函数的空间复杂度

2024-05-14

我正在阅读以下内容:https://en.wikibooks.org/wiki/Haskell/Graph_reduction https://en.wikibooks.org/wiki/Haskell/Graph_reduction,其内容如下:

棘手的空间泄漏示例:

(\xs -> head xs + last xs) [1..n]
(\xs -> last xs + head xs) [1..n]

第一个版本运行于O(1)空间。第二个在O(n).

这个说法正确吗?我看不出它们有何不同。一旦执行,它们似乎都花费相同的时间和空间,并且在执行之前您可以惰性地确定它们的类型是兼容的。


实现此目的的一种方法是手动计算表达式,并观察中间表达式的最大长度如何作为以下函数增长:n。这比听起来更棘手,因为要共享xs在你的ambas的定义中,但我会这样做,希望它会有所帮助。

首先,我们来写一下定义head and last:

head :: [a] -> a
head (a:_) = a

last :: [a] -> a
last (a:[]) = a
last (_:as) = last as

现在,有了这个,让我们做第一个:

(\xs -> head xs + last xs) [1..n]
  => let xs = [1..n] in head xs + last xs
  => let xs = 1:[2..n] in head xs + last xs
  => let xs = 1:[2..n] in 1 + last xs
  => 1 + last [2..n]
  => 1 + last (2:[3..n])
  => 1 + last [3..n]
  => 1 + last (3:[4..n])
  .
  .
  .
  => 1 + last (n:[])
  => 1 + n

正如您所看到的,中间步骤中的表达式的大小有一些恒定的上限,并且n没关系。现在让我们尝试第二个示例。我选择通过在中创建绑定列表来说明结构共享和强制let grow:

(\xs -> last xs + head xs) [1..n]
  => let xs = [1..n] in last xs + head xs
  => let xs = 1:[2..n] in last xs + head xs
  => let xs  = 1:xs2
         xs2 = 2:[3..]
     in last xs2 + head xs
  => let xs  = 1:xs2
         xs2 = 2:xs3
         xs3 = 3:[4..]
     in last xs3 + head xs
  .
  .
  .
  => let xs  = 1:xs2
         xs2 = 2:xs3
         xs3 = 3:xs4
             .
             .
             .
         xsn = n:[]
     in last xsn + head xs
  => let xs  = 1:xs2
         xs2 = 2:xs3
         xs3 = 3:xs4
             .
             .
             .
         xsn = n:[]
     in n + head xs
  => n + 1

正如您所看到的,最大表达式的大小将与n。这意味着评估使用 O(n) 空间。

这两个示例之间的差异是由于以下事实造成的:+函数在强制第二个参数之前强制其第一个参数。作为一般规则,当您有一个具有多个参数的函数时,必须在其他参数之前强制其中一个参数,并且它发生的顺序可能会产生像这样的微妙影响。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以下两个 lambda 函数的空间复杂度 的相关文章

  • Haskell - 交替两个列表中的元素

    我正在尝试编写一个 haskell 函数 它接受两个整数列表并生成一个列表 其中包含从两个列表中交替获取的元素 我有这个功能 blend xs ys 一个例子 blend 1 2 3 4 5 6 应该返回 1 4 2 5 3 6 我的逻辑是
  • 模式匹配需要圆括号来表示非空列表而不是方括号

    在 Haskell 中 为什么模式匹配期望列表在不为空时有圆括号而不是方括号 当它尝试与空列表 方括号 进行模式匹配时 为什么它不遵循相同的约定 圆括号不应该专门为元组保留吗 例如 下面不起作用 third Integral a gt a
  • Haskell GHC:具有 N 个构造函数的模式匹配的时间复杂度是多少?

    假设我们有以下 Haskell data T T0 T1 T2 TN toInt T gt Int toInt t case t of T0 gt 0 T1 gt 1 T2 gt 2 TN gt N 这里使用什么算法来执行模式匹配 我看到两
  • 在 win32/cygwin 上编译 haskell 模块网络

    我正在尝试编译 Network HTTP http hackage haskell org package network http hackage haskell org package network 在 win32 cygwin 上
  • 镜头中的观看和使用有什么区别?

    有什么区别 view MonadReader s m gt Getting a s a gt m a and use MonadState s m gt Getting a s a gt m a in 控制镜头吸气剂 https hacka
  • Haskell 单例:我们可以通过 SNat 获得什么

    我正在尝试使用 Haskell 单例 在论文中使用单例进行依赖类型编程 http cs brynmawr edu rae papers 2012 singletons paper pdf并在他的博客文章中单例 v0 9 发布 https t
  • 无法通过 cabal 安装“System.Random”

    我尝试通过 Cabal 通过 Powershell 和 Git Bash 安装 System Random 得到这个结果 PS C Users xxx gt cabal install random Resolving dependenci
  • 计算/获取分层数据的“级别”

    好吧 我真的不知道这是否是正确的标题 但我不知道如何称呼它 我的问题是关于我的作业 我现在已经工作了几个小时 主题是 函数式数据结构 我有点陷入困境 我不知道如何继续 所以我需要编写一个具有以下签名的函数 data Heap e t Hea
  • 不同 hs 文件中的函数分离时堆栈空间溢出

    我有一个巨大的 haskell 文件 它编译和运行没有任何问题 我想将一些函数和类型定义放在通用 hs 文件中的单独模块中 然后将其导入我的主模块中 虽然主程序编译时没有任何错误 它还编译导入的模块 但当我尝试运行它时 出现堆栈空间溢出 I
  • 可以通过Data.Function.fix来表达变形吗?

    我有这个可爱的fixana这里的函数执行速度比她的姐妹快 5 倍左右ana 我有一个criterion报告支持我这一点 ana alg Fix fmap ana alg alg fixana alg fix f gt Fix fmap f
  • Haskell 中的常量变量声明

    要声明常量变量 我可以在 Ruby 中执行以下操作 class COLOR RED 10 BLUE 20 GREEM 30 end COLOR RED回报10 COLOR BLUE回报20 等等 我如何在 Haskell 中实现这一点 我想
  • 谁能解释一下 GHC 对 IO 的定义吗?

    标题非常自我描述 但有一个部分引起了我的注意 newtype IO a IO State RealWorld gt State RealWorld a 剥离newtype 我们得到 State RealWorld gt State Real
  • 如何获取常量内存中的统计数据

    我有一个函数 它会创建一些随机的数值结果 我知道 结果将是 a 小 a b 约 50 范围内的整数a b 我想创建一个执行上述函数 1000000 次的函数 并计算每个结果出现的频率 该函数使用随机生成器来生成结果 问题是 我不知道如何在常
  • “反向”使用 Maybe Monad

    假设我有很多功能 f a gt Maybe a g a gt Maybe a h a gt Maybe a 我想按以下方式组合它们 如果 f 返回 Nothing 则计算 g 如果 g 返回 Nothing 则计算 h 如果其中任何一个计算
  • 列表理解:制作列表列表

    你好 我正在尝试在 haskell 中创建一个函数 该函数接受一个数字 a 使用列表 即数字 将其一部分4它会创造 1 1 1 1 1 1 2 1 3 2 2 4 我正在考虑使用列表理解来创建列表 x 然后使用 1 n 中的数字创建更多列表
  • 处理许多不相关的类型时避免样板

    我正在编写处理以下值的代码语言 扩展 注释 语法 http hackage haskell org packages archive haskell src exts 1 1 4 doc html Language Haskell Exts
  • 反应性香蕉时间延迟

    我已经查阅了文档反应香蕉 http hackage haskell org package reactive banana 而且我找不到指定明确时间延迟的方法 举例来说 我想采取Event t a并将其所有发生的事件移至未来 1 秒 或获取
  • 我应该使用什么递归方案来重复有效的操作,直到其结果符合某些标准?

    也就是说 我要问的是一个循环 effectful Int gt IO Int effectful n do putStrLn Effect show n return n condition 3 final Int gt IO final
  • 如何处理在组合下发生变化的类型?

    我最近读了一篇非常有趣的论文单调性类型 https infoscience epfl ch record 231867 files monotonicity types pdf其中描述了一种新的 HM 语言 该语言可以跟踪操作之间的单调性
  • 如何避免编写这种类型的 Haskell 样板代码

    我经常遇到这种情况 这很烦人 假设我有一个 sum 类型 它可以保存一个实例x或一堆其他无关的事情x data Foo x X x Y Int Z String other constructors not involving x 要声明

随机推荐