问题标签 [strictness]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
348 浏览

haskell - 堆栈空间溢出(可能与mapM有关)

我正在编写一个程序,该程序创建一个 shell 脚本,其中包含一个用于目录中每个图像文件的命令。目录中有 667,944 张图片,所以我需要妥善处理严格/懒惰的问题。

这是一个简单的例子,它给了我Stack space overflow。如果我给它更多空间使用它确实有效+RTS -Ksize -RTS,但它应该能够以很少的内存运行,立即产生输出。因此,我一直在阅读 Haskell wiki 和有关 Haskell 的 wikibook 中有关严格性的内容,试图找出解决问题的方法,我认为这是让我感到悲伤的 mapM 命令之一,但我仍然没有对严格性的理解不够,无法对问题进行排序。

我在 SO 上发现了一些其他似乎相关的问题(Haskell 中的 mapM 是否严格?为什么这个程序会出现堆栈溢出?以及Haskell 的 mapM 不懒惰吗?),但启蒙仍然让我望而却步。


编辑:测试#1

这是示例的最新版本。

我用命令编译它ghc --make -O2 amy2.hs -rtsopts。如果我用命令运行它./amy2 ~/nosync/GalaxyZoo/table2/images/ wombat,我会得到

如果我改为使用 command 运行它./amy2 ~/nosync/GalaxyZoo/table2/images/ wombat +RTS -K20M,我会得到正确的输出......最终:

...等等。

0 投票
3 回答
265 浏览

haskell - 键入强制执行的“严格/命令”子集/Haskell 版本

我非常喜欢 Haskell,但我担心 Haskell 的主要问题之一是难以推理空间使用情况。基本上,thunk 和递归的可能性似乎会造成一些棘手的情况,其中似乎必须通过添加正确的严格性来非常小心,以免程序在特定输入上耗尽内存。

我喜欢 C/C++ 的一点是,我可以很快确定程序空间使用的上限,尤其是在避免递归的情况下。变量一目了然。

我想知道是否有一种方法可以创建 Haskell 的类型安全“命令式”子集,它没有 thunk,并且是严格的。

我了解Data.STRef提供可变单元格,但据我了解,这些单元格本身仍然是惰性的,并且可以包含 thunk。我正在考虑强制此类单元格中的数据严格,但我不确定如何以类型系统强制执行的方式执行此操作。

我在想类似“Strict Monad”的东西,但也许这不是这样做的正确形式。

0 投票
2 回答
263 浏览

haskell - 整数累加器的严格求值

这是自定义length函数的经典第一次尝试:

这是一个尾递归版本:

但是,(n+1)不会被严格评估,但是 instad Haskell 会创建一个 thunk,对吗?

这是防止创建 thunk 的正确方法,从而强制对(n+1)?

我将如何使用seq而不是达到相同的效果$!

0 投票
2 回答
477 浏览

haskell - Haskell 中的评估和空间泄漏

我正在学习 Haskell,目前正试图将我的头包裹在 monads 上。在玩一些随机数生成时,我再次被惰性评估绊倒了。为了简化接近于:

变成这样的东西:

在更大的数量上iterations,比方说1000 * 1000 * 10,第二个示例导致堆栈溢出。

为什么第一个版本在恒定空间中愉快地运行,而第二个版本爆炸了?

更广泛地说,你能推荐一些阅读材料来改善 Haskell 懒惰评估的心智模型吗?(最好是中级入门。)因为在 Haskell 中进行评估时,我的直觉完全失败了。

0 投票
1 回答
1890 浏览

haskell - 什么是脊椎僵硬

在 Haskell 中,经常提到与惰性求值相关的术语脊椎严格性。尽管我对此含义有模糊的理解,但最好对以下内容进行更具体的解释:

  • 什么是数据结构的脊椎
  • 脊椎僵硬是什么意思?
  • 比较 Spine 严格数据结构和惰性数据结构有什么好处?
0 投票
3 回答
251 浏览

haskell - IO monad 的逻辑与严格性

我正在尝试在 Haskell 中编写一个简单的程序。它基本上应该并行运行两个 shell 命令。这是代码:

但是命令“foo”返回 ExitFailure,我希望“bar”永远不会运行。不是这种情况!它们都运行并且都在控制台上显示错误。

同时

评价很好;这意味着不计算第二个参数。如何在我的应用程序中对系统命令执行相同操作?

0 投票
1 回答
201 浏览

haskell - 弱头范式和求值顺序

我已经阅读了很多关于弱头正常形式和序列的内容。但是我仍然无法想象 Haskell 评估顺序背后的逻辑

演示何时以及如何使用的常见示例,但我仍然不明白常见示例如何

可能导致堆栈溢出。而另一个折叠定义使用seq

从我读过的对 seq 的解释中,作者非常小心地阐明了以下内容:

  • 的第一个参数seq不能保证在第二个参数之前被评估
  • 的第一个参数seq只会被评估为弱头范式
  • 的第一个参数的评估seq只会在第二个评估为 WHNF 时发生

那么,如果以上是正确的(是吗?)那么为什么不foldl'溢出foldl呢?

当我们减少一个步骤时,它不应该是这样的吧?

在上面,第二个参数seq不在 WHNF 中,因为需要完成一个函数应用程序。seq我们是否保证在到达第二个参数的 WHNF 之前评估这里的第一个参数?

0 投票
1 回答
171 浏览

haskell - 枚举通用实例的所有值时无限递归

对于我的另一个答案,我编写了以下代码,为 enumerable提供了对角遍历 的实例(它从那里的版本略有更新,但使用相同的逻辑):UniverseGeneric

Omega可能与问题无关,但是问题的一部分。)

这适用于大多数类型,甚至是递归类型:

例子:

但请注意,上述类型都不是一开始就有递归构造函数!事实上(这就是问题所在),存在以下分歧:

我首先认为可能有一些与Omegas' 的评估顺序有关的东西,但是将左右部分交换成行(2)只会T7起作用,而T6失败,这是我所期望的正确行为。

我目前的怀疑是对universein line的调用(1)评估得太早了。例如,以下也有分歧,而列表中应该只有一个值,甚至不应该评估:

因此,唯一的实例 ,在 list 中T8 (T8 (...) ... )被评估,即使它不是必需的!我不知道这个效果是从哪里来的——它是递归使用它自己的实例吗?但是,为什么“右递归”类型的行为正确,而“左递归”类型 ( ) 却没有呢?UniverseT6T7

这是一个严格的问题吗?如果是这样,在代码的哪一部分?我的Universe实例?Generic? 以及如何解决?如果这很重要,我使用 GHC 7.6.3。

0 投票
2 回答
121 浏览

haskell - 关于 haskell 的严格性

我创建了以下 Haskell 素数函数(在 ghci 中):

请不要介意第二个/记忆的参数(它应该总是从 2 开始)。当然,正如预期的那样,thunk 很快就会失控。确认 43 是第 14 个素数需要超过 19 秒...

我已经阅读了严格性(seq主要$!是),但我所有的尝试都花费了更长的时间!

0 投票
1 回答
436 浏览

haskell - 更严格的 Control.Monad.Trans.Writer.Strict

所以我们有:

对于一些KeyVal

只要我们不查看收集的输出,一切正常:

但是,如果我们要检查w,我们会得到堆栈溢出。

我认为原因是因为(>>=)forWriter 被定义为

如果我有一个大的Writer a计算,它会建立一个很长的 mappends 序列:w <> (w' <> (w'' <> ...))在这种情况下,Map.union这在地图的脊椎中是严格的。因此,如果我建立了大量的联合,则必须在我强制使堆栈溢出的 Map 时立即评估整个事情。

我们想要的是尽早执行联合。我们想要一个更严格的 Strict.Writer:

所以我的问题是:这是否存在于某些“标准”库中?如果不是,为什么不呢?