Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 模式匹配时,(x:xs)中的括号表示什么?_Haskell_Syntax - Fatal编程技术网

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

Haskell 模式匹配时,(x:xs)中的括号表示什么?,haskell,syntax,Haskell,Syntax,当您使用x:xs语法拆分列表时,为什么要将其包装在括号中?括号的意义是什么?为什么不使用[x:xs]或仅使用x:xs?您只是在使用cons运算符:,它的优先级较低。括号是必要的,这样事情就不会出错 你不用[x:xs],因为这会匹配一个列表,它的唯一元素是一个头x尾xs的列表,我不知道确切的答案,但我想这是因为可以在模式中匹配什么。只能匹配构造函数。构造函数可以是单个单词或复合词。看看下面的代码: data Foo = Bar | Baz Int f :: Foo -> Int f Bar

当您使用x:xs语法拆分列表时,为什么要将其包装在括号中?括号的意义是什么?为什么不使用[x:xs]或仅使用x:xs?

您只是在使用cons运算符
,它的优先级较低。括号是必要的,这样事情就不会出错


你不用
[x:xs]
,因为这会匹配一个列表,它的唯一元素是一个头
x
xs
的列表,我不知道确切的答案,但我想这是因为可以在模式中匹配什么。只能匹配构造函数。构造函数可以是单个单词或复合词。看看下面的代码:

data Foo = Bar | Baz Int

f :: Foo -> Int
f Bar     = 1
f (Baz x) = x - 1
单字构造函数按原样匹配。但是复合构造函数必须被paren包围,以避免歧义。如果我们跳过parens,它看起来像是针对两个独立参数进行匹配:

f Baz x = x - 1
因此,由于
(:)
是复合的,所以它必须在parens中。跳过
Bar
的paren是一种语法糖分


更新:我意识到(正如sykora所指出的)这是运算符优先级的结果。它澄清了我的假设。函数应用程序(函数和参数之间的空格)具有最高优先级。其他包括(:)的优先级较低。所以
fx:xs
被解释为
((:)(fx))xs
,这大概不是我们需要的。而
f(x:xs)
被解释为
f
应用于
x:xs
,这又是
(:)
应用于
x
xs
,这与解析有关

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

foo [] = 0
foo (x:xs) = x + foo xs
也可以写成

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

如果将括号放在最后一行中,将很难解析

是一个数据构造函数,与任何其他模式匹配一样,但都是用中缀编写的。括号的存在纯粹是因为中缀优先;它们实际上不是必需的,并且可以在优先规则允许的情况下安全地省略。例如:

> let (_, a:_) = (1, [2, 3, 4]) in a
2
> let a:_ = "xyzzy"
'x'
> case [1, 2, 3] of; a:b -> a; otherwise -> 0;
1
有趣的是,这在一个lambda的脑袋里似乎不起作用。不知道为什么


与往常一样,“并置”操作符绑定得比任何其他操作符都要紧密,因此通常需要分隔符,但它们实际上不是模式匹配的一部分——否则您将无法使用像
(x:y:zs)
这样的模式,而不是
(x:y:zs))

cons单元格不必在所有上下文中都加括号,但在大多数上下文中,这是因为

函数应用程序绑定比任何中缀运算符都要紧密。 用火书的形式把它烧进你的大脑

例如:

length [] = 0
length (x:xs) = 1 + length xs
如果省略括号,编译器会认为您的参数
x
后面跟了一个位置不正确的中缀运算符,它会发出痛苦的抱怨。另一方面,这是可以的

length l = case l of [] -> 0
                     x:xs -> 1 + length xs
在这种情况下,
x
xs
都不可能被解释为函数应用程序的一部分,因此不需要括号


请注意,相同的奇妙规则函数应用程序绑定比任何中缀运算符都要紧密,它允许我们在
1+length xs
中写入
length xs
,而无需任何括号。中缀规则给出,中缀规则带走。

您有没有一个例子说明它在()中的包装位置?x:xs可以按原样用于描述具有列表的第一个元素的列表。[x:xs]将是一个包含列表x:xs的列表。他说的是模式匹配,而不是构建列表。我从未尝试过那种特定的
[x:xs]
模式,但你当然是对的;它与顶层的单例列表相匹配。该模式的脱模符号为:
((x:xs):[])
+1表示火灾字母。在我内化了这个规则之后,我的Haskell代码就不再像Lisp了。