在Haskell中, "@" 符号代表什么?与列表有关。

155

我遇到了一段类似于下面的Haskell代码:

ps@(p:pt)

在这个上下文中,@符号是什么意思?我在Google上找不到任何信息(很不幸,在Google上搜索符号很困难),并且我在Prelude文档中也找不到这个函数,所以我想它必须是某种语法糖。


16
不要试图搜索特定的符号。搜索 Haskell 语法总体,然后在该总体讨论中找到该符号。例如,“Haskell 语法”的顶部谷歌搜索结果:http://www.cs.utep.edu/cheon/cs3360/pages/haskell-syntax.html。该页面上第二次出现 @ 符号进行了解释。 - Rob Kennedy
1
好在我详细说明了我是如何找到那个URL的,@Iter。今天任何人都可以重复这个过程,在他们找到的任何页面上找到答案。 - Rob Kennedy
4个回答

209

是的,这只是语法糖,@ 读作 "as"。 ps@(p:pt) 让你获得以下名称:

  1. 列表: ps
  2. 列表头部: p
  3. 列表尾部: pt

如果没有 @,你只能在以下选项(1)和(2)中做出选择:(3)。

实际上,这种语法对于任何构造函数都适用;如果有 data Tree a = Tree a [Tree a],那么 t@(Tree _ kids) 允许您访问树以及其子节点。


4
你知道这种语法的名称吗? - danza
13
它被称为“as模式”。 - adamo

55
< p >符号@既用于为参数命名,又用于将该参数与跟在@后面的模式匹配。它不仅适用于列表,还可用于其他数据结构。

如果您想要将一个参数“分解”为其各个部分,同时仍需要在函数的某个地方使用整个参数,则这非常有用。一个示例是标准库中的tails函数。

tails                   :: [a] -> [[a]]
tails []                =  [[]]
tails xxs@(_:xs)        =  xxs : tails xs

29

我想补充一下,@ 在所有级别都可用,这意味着你可以这样做:

let a@(b@(Just c), Just d) = (Just 1, Just 2) in (a, b, c, d)

然后生成这个结果:((Just 1, Just 2), Just 1, 1, 2)

基本上它是一种将模式绑定到值的方法。这也意味着它适用于任何类型的模式,而不仅仅是列表,如上面所示。这是一个非常有用的知识,因为它意味着你可以在更多的情况下使用它。

在这种情况下,a 是整个 Maybe Tupleb 只是元组中第一个 Justcd 分别是元组中第一个和第二个 Just 中包含的值。


12

除了其他人说的之外,它们被称为作为模式(在ML中,语法使用关键字“as”),并在Haskell报告的模式部分中描述。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接