Haskell声明中的惊叹号是什么意思? [英] What does the exclamation mark mean in a Haskell declaration?

查看:159
本文介绍了Haskell声明中的惊叹号是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我试图通过一个真正的项目来学习Haskell来驱动它时,我遇到了下面的定义。我不明白每个参数前面的感叹号是什么意思,我的书似乎没有提到它。

 数据MidiMessage = MidiMessage!Int!MidiMessage 


解决方案

宣言。基本上,这意味着当创建数据结构值时,必须对所谓的弱正常头部形式进行评估。让我们来看一个例子,以便我们可以看到这意味着什么:

  data Foo = Foo Int Int!Int!(可能是Int)

f = Foo(2 + 2)(3 + 3)(4 + 4)(Just(5 + 5))

上面的函数 f 在计算时会返回一个thunk:也就是要执行的代码弄清楚它的价值。在那个时候,一个Foo甚至还不存在,只是代码。



但是在某些时候,有人可能会试着去查看它,可能是通过模式匹配:

 情况f 
Foo 0 _ _ _ - > 第一个参数为零
_ - > 首先是另一回事

这将执行足够的代码来执行所需的操作,并且不再。所以它会创建一个带有四个参数的Foo(因为如果没有这个参数,你就无法查看它)。第一,因为我们正在测试它,所以我们需要评估一直到 4 ,我们意识到它不匹配。



第二个不需要评估,因为我们没有测试它。因此,我们将存储代码以便稍后进行评估,而不是将 6 存储在该内存位置中,(3 + 3) code>。然而,第三个参数有一个在它的前面,所以严格评估:(4 + 4)被执行,并且 8 被存储在内存位置。



第四个参数也被严格评估。但是,这里有点棘手:我们不是完全评估,而只是对弱的正常头部形式。这意味着我们要弄清它是否是 Nothing Just >,并存储它,但我们不会再继续。这意味着我们不存储 Just 10 ,但实际上 Just(5 + 5),使得thunk内部未被评估。这很重要,但我认为这个问题的所有含义都超出了这个问题的范围。



您可以用同样的方式注释函数参数,if您启用 BangPatterns 语言扩展:

  fx!y = x * y 

f(1 + 1)(2 + 2)将返回thunk (1 + 1)* 4


I came across the following definition as I try to learn Haskell using a real project to drive it. I don't understand what the exclamation mark in front of each argument means and my books didn't seem to mention it.

data MidiMessage = MidiMessage !Int !MidiMessage

解决方案

It's a strictness declaration. Basically, it means that it must be evaluated to what's called "weak normal head form" when the data structure value is created. Let's look at an example, so that we can see just what this means:

data Foo = Foo Int Int !Int !(Maybe Int)

f = Foo (2+2) (3+3) (4+4) (Just (5+5))

The function f above, when evaluated, will return a "thunk": that is, the code to execute to figure out its value. At that point, a Foo doesn't even exist yet, just the code.

But at some point someone may try to look inside it, probably through a pattern match:

case f of
     Foo 0 _ _ _ -> "first arg is zero"
     _           -> "first arge is something else"

This is going to execute enough code to do what it needs, and no more. So it will create a Foo with four parameters (because you can't look inside it without it existing). The first, since we're testing it, we need to evaluate all the way to 4, where we realize it doesn't match.

The second doesn't need to be evaluated, because we're not testing it. Thus, rather than 6 being stored in that memory location, we'll just store the code for possible later evaluation, (3+3). That will turn into a 6 only if someone looks at it.

The third parameter, however, has a ! in front of it, so is strictly evaluated: (4+4) is executed, and 8 is stored in that memory location.

The fourth parameter is also strictly evaluated. But here's where it gets a bit tricky: we're evaluating not fully, but only to weak normal head form. This means that we figure out whether it's Nothing or Just something, and store that, but we go no further. That means that we store not Just 10 but actually Just (5+5), leaving the thunk inside unevaluated. This is important to know, though I think that all the implications of this go rather beyond the scope of this question.

You can annotate function arguments in the same way, if you enable the BangPatterns language extension:

f x !y = x*y

f (1+1) (2+2) will return the thunk (1+1)*4.

这篇关于Haskell声明中的惊叹号是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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