Haskell的'seq'与其他函数有什么不同? [英] How is Haskell's 'seq' different from other functions?

查看:127
本文介绍了Haskell的'seq'与其他函数有什么不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对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 evaluate x to WHNF and only then continue with the evaluation of y

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆