当模式匹配时,括号在(x:xs)中表示什么?

时间:2021-03-11 16:59:39

when you split a list using x:xs syntax why is it wrapped in a parentheses? what is the significance of the parentheses? why not [x:xs] or just x:xs?

当您使用x:xs语法拆分列表时,为什么要用括号括起来?括号的意义是什么?为什么不[x:xs]或x:xs?

5 个解决方案

#1


42  

The cons cell doesn't have to be parenthesized in every context, but in most contexts it is because

在每个上下文中,都不需要括号,但是在大多数情况下,这是因为。

Function application binds tighter than any infix operator.

Burn this into your brain in letters of fire.

把这些都烙进你的脑子里。

Example:

例子:

length [] = 0
length (x:xs) = 1 + length xs

If parentheses were omitted the compiler would think you had an argument x followed by an ill-placed infix operator, and it would complain bitterly. On the other hand this is OK

如果省略了括号,编译器会认为您有一个参数x,然后是一个错误的infix操作符,它会痛苦地抱怨。另一方面,这是可以的。

length l = case l of [] -> 0
                     x:xs -> 1 + length xs

In this case neither x nor xs can possibly be construed as part of a function application so no parentheses are needed.

在这种情况下,x和xs都不可能被解释为函数应用程序的一部分,因此不需要括号。

Note that the same wonderful rule function application binds tighter than any infix operator is what allows us to write length xs in 1 + length xs without any parentheses. The infix rule giveth and the infix rule taketh away.

请注意,同样出色的规则函数应用程序绑定比任何infix操作符更紧密,这使得我们可以在1 +长度xs中不使用任何圆括号来写入长度xs。infix规则和infix规则都被取消了。

#2


14  

You're simply using the cons operator :, which has low precedence. Parentheses are needed so that things stay right.

您只需使用cons操作符:它的优先级较低。括号是必要的,这样东西就可以保持正确。

And you don't use [x:xs], because that would match a list whose only element is a list with head x and tail xs.

你不用[x:xs],因为那将会匹配一个列表,它的唯一元素是一个带有头x和尾x的列表。

#3


3  

I don't know exact answer, but I guess that is due to what can be matched in patterns. Only constructors can be matched. Constructors can be of single word or composite. Look at the next code:

我不知道确切的答案,但我想这是由于可以匹配的模式。只有构造函数可以匹配。构造函数可以是单个字或复合结构。看看下面的代码:

data Foo = Bar | Baz Int

f :: Foo -> Int
f Bar     = 1
f (Baz x) = x - 1

Single word constructors match as is. But composite constructors must be surrounded with parens in order to avoid ambiguity. If we skip parens it looks like matching against two independent arguments:

单字构造器匹配。但是,为了避免歧义,必须将复合构造函数包围起来。如果我们跳过parens,它看起来就像与两个独立的参数相匹配:

f Baz x = x - 1

So, as (:) is composite it must be in parens. Skipping parens for Bar is a kind of syntactic sugar.

因此,as(:)是复合的,它必须是在parens中。跳绳是一种语法糖。

UPDATE: I realized that (as sykora noted) it is a consequence of operator precedence. It clarifies my assumptions. Function application (which is just space between function and argument) has highest precedence. Others including (:) have lower precedence. So f x:xs is to be interpreted as ((:) (f x)) xs that is presumably not what we need. While f (x:xs) is interpreted as f applied to x:xs which is in turn (:) applied to x and xs.

更新:我意识到(正如sykora所指出的),它是操作符优先级的结果。澄清我的假设。函数应用程序(即函数和参数之间的空间)具有最高的优先级。其他包括(:)的优先级较低。因此,f x:xs将被解释为(:)(f x) xs,这大概不是我们所需要的。当f (x:xs)被解释为f应用到x:xs,它反过来(:)应用于x和xs。

#4


2  

It's to do with parsing.

这与解析有关。

Remember, the colon : is just a constructor that's written with operator syntax. So a function like

记住,冒号:只是一个用运算符语法编写的构造函数。所以一个函数

foo [] = 0
foo (x:xs) = x + foo xs

could also be written as

也可以写成?

foo [] = 0
foo ((:) x xs) = x + foo xs

If you drop the parenthesis in that last line, it becomes very hard to parse!

如果在最后一行中插入括号,就很难解析了!

#5


1  

: is a data constructor, like any other pattern match, but written infix. The parentheses are purely there because of infix precedence; they're actually not required and can be safely omitted when precedence rules allow. For instance:

:是一个数据构造函数,就像其他模式的匹配一样,但它是写infix的。括号是纯粹的,因为有infix优先级;它们实际上不是必需的,当优先规则允许时可以安全地省略它们。例如:

> let (_, a:_) = (1, [2, 3, 4]) in a
2
> let a:_ = "xyzzy"
'x'
> case [1, 2, 3] of; a:b -> a; otherwise -> 0;
1

Interestingly, that doesn't seem to work in the head of a lambda. Not sure why.

有趣的是,这似乎并不适用于lambda。不知道为什么。

As always, the "juxtaposition" operator binds tighter than anything else, so more often than not the delimiters are necessary, but they're not actually part of the pattern match--otherwise you wouldn't be able to use patterns like (x:y:zs) instead of (x:(y:zs)).

与往常一样,“并置”操作符绑定的比其他任何东西都更紧密,所以通常是必须的分隔符,但它们实际上并不是模式匹配的一部分——否则您将无法使用(x:y:zs)而不是(x:y:zs)的模式。

#1


42  

The cons cell doesn't have to be parenthesized in every context, but in most contexts it is because

在每个上下文中,都不需要括号,但是在大多数情况下,这是因为。

Function application binds tighter than any infix operator.

Burn this into your brain in letters of fire.

把这些都烙进你的脑子里。

Example:

例子:

length [] = 0
length (x:xs) = 1 + length xs

If parentheses were omitted the compiler would think you had an argument x followed by an ill-placed infix operator, and it would complain bitterly. On the other hand this is OK

如果省略了括号,编译器会认为您有一个参数x,然后是一个错误的infix操作符,它会痛苦地抱怨。另一方面,这是可以的。

length l = case l of [] -> 0
                     x:xs -> 1 + length xs

In this case neither x nor xs can possibly be construed as part of a function application so no parentheses are needed.

在这种情况下,x和xs都不可能被解释为函数应用程序的一部分,因此不需要括号。

Note that the same wonderful rule function application binds tighter than any infix operator is what allows us to write length xs in 1 + length xs without any parentheses. The infix rule giveth and the infix rule taketh away.

请注意,同样出色的规则函数应用程序绑定比任何infix操作符更紧密,这使得我们可以在1 +长度xs中不使用任何圆括号来写入长度xs。infix规则和infix规则都被取消了。

#2


14  

You're simply using the cons operator :, which has low precedence. Parentheses are needed so that things stay right.

您只需使用cons操作符:它的优先级较低。括号是必要的,这样东西就可以保持正确。

And you don't use [x:xs], because that would match a list whose only element is a list with head x and tail xs.

你不用[x:xs],因为那将会匹配一个列表,它的唯一元素是一个带有头x和尾x的列表。

#3


3  

I don't know exact answer, but I guess that is due to what can be matched in patterns. Only constructors can be matched. Constructors can be of single word or composite. Look at the next code:

我不知道确切的答案,但我想这是由于可以匹配的模式。只有构造函数可以匹配。构造函数可以是单个字或复合结构。看看下面的代码:

data Foo = Bar | Baz Int

f :: Foo -> Int
f Bar     = 1
f (Baz x) = x - 1

Single word constructors match as is. But composite constructors must be surrounded with parens in order to avoid ambiguity. If we skip parens it looks like matching against two independent arguments:

单字构造器匹配。但是,为了避免歧义,必须将复合构造函数包围起来。如果我们跳过parens,它看起来就像与两个独立的参数相匹配:

f Baz x = x - 1

So, as (:) is composite it must be in parens. Skipping parens for Bar is a kind of syntactic sugar.

因此,as(:)是复合的,它必须是在parens中。跳绳是一种语法糖。

UPDATE: I realized that (as sykora noted) it is a consequence of operator precedence. It clarifies my assumptions. Function application (which is just space between function and argument) has highest precedence. Others including (:) have lower precedence. So f x:xs is to be interpreted as ((:) (f x)) xs that is presumably not what we need. While f (x:xs) is interpreted as f applied to x:xs which is in turn (:) applied to x and xs.

更新:我意识到(正如sykora所指出的),它是操作符优先级的结果。澄清我的假设。函数应用程序(即函数和参数之间的空间)具有最高的优先级。其他包括(:)的优先级较低。因此,f x:xs将被解释为(:)(f x) xs,这大概不是我们所需要的。当f (x:xs)被解释为f应用到x:xs,它反过来(:)应用于x和xs。

#4


2  

It's to do with parsing.

这与解析有关。

Remember, the colon : is just a constructor that's written with operator syntax. So a function like

记住,冒号:只是一个用运算符语法编写的构造函数。所以一个函数

foo [] = 0
foo (x:xs) = x + foo xs

could also be written as

也可以写成?

foo [] = 0
foo ((:) x xs) = x + foo xs

If you drop the parenthesis in that last line, it becomes very hard to parse!

如果在最后一行中插入括号,就很难解析了!

#5


1  

: is a data constructor, like any other pattern match, but written infix. The parentheses are purely there because of infix precedence; they're actually not required and can be safely omitted when precedence rules allow. For instance:

:是一个数据构造函数,就像其他模式的匹配一样,但它是写infix的。括号是纯粹的,因为有infix优先级;它们实际上不是必需的,当优先规则允许时可以安全地省略它们。例如:

> let (_, a:_) = (1, [2, 3, 4]) in a
2
> let a:_ = "xyzzy"
'x'
> case [1, 2, 3] of; a:b -> a; otherwise -> 0;
1

Interestingly, that doesn't seem to work in the head of a lambda. Not sure why.

有趣的是,这似乎并不适用于lambda。不知道为什么。

As always, the "juxtaposition" operator binds tighter than anything else, so more often than not the delimiters are necessary, but they're not actually part of the pattern match--otherwise you wouldn't be able to use patterns like (x:y:zs) instead of (x:(y:zs)).

与往常一样,“并置”操作符绑定的比其他任何东西都更紧密,所以通常是必须的分隔符,但它们实际上并不是模式匹配的一部分——否则您将无法使用(x:y:zs)而不是(x:y:zs)的模式。