问题标签 [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.
haskell - 未装箱类型和严格性之间有什么关系?
未装箱的类型,likeInt#
和严格的函数,likef (!x) = ...
是不同的,但我看到概念上的相似性——它们在某种程度上不允许 thunk/laziness。如果 Haskell 是像 Ocaml 这样的严格语言,那么每个函数都将是严格的,并且每个类型都是未装箱的。未装箱类型与执行严格性之间有什么关系?
haskell - Haskell中并发通道的严格评估技术
我正在玩弄 Haskell 线程,并且遇到了跨通道传达惰性求值值的问题。例如,在 N 个工作线程和 1 个输出线程的情况下,工作人员交流未评估的工作,输出线程最终为他们完成工作。
我已经在各种文档中阅读了有关此问题的信息并查看了各种解决方案,但我只找到了一个有效的解决方案,而其余的则没有。下面是一些代码,其中工作线程开始一些可能需要很长时间的计算。我按降序启动线程,这样第一个线程应该花费最长的时间,后面的线程应该更早完成。
使用大多数技术,结果按产生的顺序报告;也就是说,运行时间最长的计算在前。我将此解释为意味着输出线程正在完成所有工作:
我认为这个问题的答案将是严格的渠道,但他们没有奏效。我知道字符串的 WHNF 是不够的,因为这只会强制最外层的构造函数(字符串的第一个字符为 nil 或 cons)。应该完全评估rdeepseq
,但它没有区别。我发现唯一可行的方法是映射Control.Exception.evaluate :: a -> IO a
字符串中的所有字符。(请参阅force
代码中的函数注释以了解几种不同的替代方案。)结果Control.Exception.evaluate
如下:
那么为什么不严格渠道或rdeepseq
产生这种结果呢?还有其他技术吗?我是否误解了为什么第一个结果被破坏了?
haskell - haskell中列表的强制严格性
我制作了非常耗时的算法,结果产生了一个短字符串。当我尝试打印它(通过 putStrLn)时,它一个字符一个字符地出现在屏幕上。我确实理解为什么会发生这种情况,并且我试图在实际打印之前强制评估字符串。
但这帮助很小。当我在调试中运行程序时,我注意到 !str 仅对第一个字符进行强制评估。
有谁知道这是为什么,以及如何处理?
performance - 如何在haskell中使表(Data.Map)严格?
为了学习 Haskell(好语言),我正在尝试 Spoj 的问题。
我有一个包含 19000 个元素的表,这些元素在编译时都是已知的。如何使用“seq”使表格严格?这是我的代码中的一个(强)简化示例。
haskell - 为什么 map 不强制严格而 zipWith 强制?
zipWith 函数有两个严格版本:
1) 非常严格,列表 l1 和 l2 的元素得到评估,因此它们的 thunk 不会占用所有堆栈空间(Don Stewart 代码)
2)不是很严格,尝试通过其他方式强制评估。
问题是:为什么使用map的第二个示例中的等效代码不会使函数也严格?
haskell - 什么是弱头范式?
弱头范式(WHNF) 是什么意思?头范式 ( HNF) 和范式(NF) 是什么意思?
熟悉的
seq
函数将表达式计算为我们所说 的头部范式 (缩写为 HNF)。一旦到达最外层的构造函数(“头部”),它就会停止。这与 标准形式 (NF) 不同,在标准形式中,表达式被完全评估。您还会听到 Haskell 程序员提到 弱 头范式 (WHNF)。对于法线数据,弱头范式与头范式相同。区别只出现在功能上,而且太深奥了,我们在这里不关心。
我已经阅读了一些资源和定义(Haskell Wiki和Haskell Mail List和Free Dictionary),但我不明白。有人可以举个例子或提供一个外行定义吗?
我猜它会类似于:
WHNFseq
和($!)
HNF 有什么关系?
更新
我仍然很困惑。我知道一些答案说忽略 HNF。从阅读各种定义来看,WHNF 和 HNF 中的常规数据似乎没有区别。但是,在功能方面似乎确实存在差异。如果没有区别,为什么seq
需要foldl'
?
另一个混淆点来自 Haskell Wiki,它指出seq
简化为 WHNF,并且不会对以下示例执行任何操作。然后他们说他们必须使用seq
强制评估。这不是强迫它到HNF吗?
常见新手栈溢出代码:
了解 seq 和弱头范式 (whnf) 的人可以立即明白这里出了什么问题。
(acc+x, len+1)
已经在 whnf 中,因此seq
(在 的定义中foldl'
)将值减少为 whnf,对此没有任何作用。这段代码将像原始示例一样构建 thunkfoldl
,它们只是在一个元组中。解决方案只是强制元组的组件,例如
haskell - Haskell 的严格点是什么?
我们都知道(或应该知道)Haskell 默认是惰性的。在必须评估之前,不会评估任何内容。那么什么时候必须评估一些东西呢?Haskell 在某些方面必须严格。我称这些为“严格点”,尽管这个特定的术语并不像我想象的那么普遍。据我说:
Haskell 中的缩减(或评估)只发生在严格点上。
所以问题是: Haskell 的严格点究竟是什么?我的直觉说main
, seq
/ bang 模式、模式匹配以及IO
通过执行的任何操作main
都是主要的严格点,但我真的不知道为什么我知道这一点。
(另外,如果它们不被称为“严格点”,它们叫什么?)
我想一个好的答案将包括一些关于 WHNF 等的讨论。我还想它可能会涉及 lambda 演算。
编辑:关于这个问题的其他想法。
正如我对这个问题的反思,我认为在严格点的定义中添加一些内容会更清楚。严格点可以有不同的上下文和不同的深度(或严格性)。回到我的定义,“Haskell 中的缩减只发生在严格点”,让我们在该定义中添加这个子句:“严格点只在其周围的上下文被评估或缩减时才被触发。”
所以,让我试着让你开始我想要的那种答案。main
是一个严格点。它被特别指定为其上下文的主要严格点:程序。当程序(main
的上下文)被评估时, main 的严格点被激活。Main 的深度最大:必须对其进行全面评估。Main 通常由 IO 动作组成,这些动作也是严格点,其上下文为main
.
现在你试试:seq
用这些术语讨论和模式匹配。解释函数应用的细微差别:它有多严格?怎么不是?怎么样deepseq
?let
和case
声明?unsafePerformIO
? Debug.Trace
? 顶级定义?严格的数据类型?爆炸模式?等等。这些项目中有多少可以仅用 seq 或模式匹配来描述?
haskell - Haskell 中的运算符 && 是否严格?
例如,我有一个在返回fnB :: a -> Bool
之前没有意义的操作。在 CI 中可以将这两个操作组合在一个块中:fnA :: Bool
False
if
并且 C 将保证在返回 falsefnB
之前不会执行。fnA
但是 Haskell 是懒惰的,而且通常不能保证首先执行什么操作,除非我们不使用seq
,$!
或其他东西来使我们的代码严格。一般来说,这就是我们需要快乐的东西。但是使用&&
运算符,我希望在返回结果fnB
之前不会对其进行评估。fnA
Haskell 是否提供这样的保证&&
?fnB
即使fnA
返回 False ,Haskell 也会进行评估吗?
haskell - foldl 是否比它严格的表亲 foldl' 更可取?
Haskell 有两个用于列表的左折叠函数:foldl
和一个“严格”版本,foldl'
. 非严格的问题foldl
在于它构建了一个 thunk 塔:
这会浪费内存,如果列表中的项目太多,可能会导致堆栈溢出。 foldl'
,另一方面,在每个项目上强制累加器。
但是,据我所知,foldl'
在语义上等同于foldl
. 评估foldl (+) 0 [1..5]
头部正常形式需要在某个点强制累加器。如果我们不需要一个 head-normal 形式,我们就不会foldl (+) 0 [1..5]
开始评估。
是否有任何令人信服的理由想要 的 行为foldl
超过 的foldl'
?