Haskell的'seq'与其他函数有什么不同? [英] How is Haskell's 'seq' different from other functions?
问题描述
我对Haskell的 seq
如何在教程我正在阅读。
本教程指出:
评估表达式
seq xy
将首先评估x
为WHNF,然后继续评估y
但是之前的同一篇教程解释了Haskell懒惰评估的工作原理一般来说,在评估一个函数时,争论是被评估的,但只是在必要的时候,这意味着它的
参数将会是从左到右进行评估,直到它们的最顶层节点是与模式匹配的构造函数。如果模式是一个简单的变量,那么参数不会被评估;如果这个模式是一个构造函数,这意味着对WHNF的评估。
这个函数评估的描述一般来说似乎与描述没有什么不同给出 seq
。两者 - 在我的初学者的阅读中 - 只是减少他们对WHNF的第一个论点。
这是正确的吗? seq
如何处理它的第一个参数 - 从任何其他Haskell函数中获取?
seq
, evaluate
,爆炸模式等,则以下规则适用: $ b
所有评估都是直接通过模式匹配来驱动的,如果条件评估
,或者原始的数字操作。
事实证明,我们可以眯起一点,使所有这些 like pattern matching:
if c then x else y
=
case c of
真 - > x
False - > y
x> y =
的情况x 0 - > ...
0 + y = y
1 + 1 = 2
等。最终,任何时候被评估的东西都是程序将要执行的下一个原始 IO
动作,其他所有事情都是由模式匹配递归驱动的。
从左到右的业务意味着,例如,
foo False' d'= ...
foo True _ = ...
相当于
foo xy = case x of
False - >案例y的
'd' - > ...
True - > ...
因此,如果应用 foo
到 True
和其他一些值,它并不会强迫这个值,因为它首先检查左边的模式。
seq
应用于数据时,就像一个愚蠢的 case
。如果 x :: Bool
,那么
x`seq` y =案例x的
真 - > y
False - > y
但是 seq
也可以应用于功能,也可以应用于未知类型的事物。它提供了一种方法来强制评估除之外的事物和通常的模式匹配链。
在Haskell的早期阶段, seq
是一个 Seq
类的方法,这很有意义。不幸的是,实施者发现,如果仅仅欺骗并且使得 seq
适用于所有事情,那么就不得不处理该类。所以他们欺骗了,程序分析和转换的某些方面从此变得更加困难。
I'm confused about the description of how Haskell's seq
works in a tutorial I'm reading.
The tutorial states that
evaluating the expression
seq x y
will first evaluatex
to WHNF and only then continue with the evaluation ofy
But earlier the same tutorial, in explaining how Haskell's lazy evaluation works in general, states that in evaluating a function, argues are "evaluated, but only as far as necessary" which means that its
arguments will be evaluated from left to right until their topmost nodes are constructors that match the pattern. If the pattern is a simple variable, then the argument is not evaluated; if the pattern is a constructor, this means evaluation to WHNF.
This description of function evaluation in general, seems no different from the description given for seq
. Both — in my beginner's reading — just reduce their first argument to WHNF.
Is that correct? How is seq
different — specifically in how it processes its first argument — from any other Haskell function?
Without seq
, evaluate
, bang patterns, etc., the following rule applies:
All evaluation is driven directly by pattern matching, evaluation of
if
conditions, or primitive numerical operations.
As it turns out, we can squint a bit and make all of those look like pattern matching:
if c then x else y
=
case c of
True -> x
False -> y
x > y = case x of
0 -> case y of ...
0 + y = y
1 + 1 = 2
etc. Ultimately, the thing being evaluated at any time is the very next primitive IO
action the program will take, and everything else is just recursively driven by pattern matching.
The left-to-right business means that, for instance,
foo False 'd' = ...
foo True _ = ...
is equivalent to
foo x y = case x of
False -> case y of
'd' -> ...
True -> ...
So if foo
is applied to True
and some other value, it doesn't bother forcing that value because it checks the left pattern first.
seq
, when applied to data, acts just like a silly case
. If x :: Bool
, then
x `seq` y = case x of
True -> y
False -> y
But seq
can, rather shadily, be applied to functions as well, or to things of unknown type. It offers a way to force evaluation of things aside from the usual chain of pattern matching.
In the early days of Haskell, seq
was a method of a Seq
class, and this made good sense. Unfortunately, the implementers found it annoying to have to deal with that class when it was easier to just "cheat" and make seq
work for everything. So they cheated, and certain aspects of program analysis and transformation have been harder ever since.
这篇关于Haskell的'seq'与其他函数有什么不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!