我遇到了一段类似于下面的Haskell代码:
ps@(p:pt)
在这个上下文中,@
符号是什么意思?我在Google上找不到任何信息(很不幸,在Google上搜索符号很困难),并且我在Prelude文档中也找不到这个函数,所以我想它必须是某种语法糖。
是的,这只是语法糖,@
读作 "as"。 ps@(p:pt)
让你获得以下名称:
ps
p
pt
如果没有 @
,你只能在以下选项(1)和(2)中做出选择:(3)。
实际上,这种语法对于任何构造函数都适用;如果有 data Tree a = Tree a [Tree a]
,那么 t@(Tree _ kids)
允许您访问树以及其子节点。
@
既用于为参数命名,又用于将该参数与跟在@
后面的模式匹配。它不仅适用于列表,还可用于其他数据结构。如果您想要将一个参数“分解”为其各个部分,同时仍需要在函数的某个地方使用整个参数,则这非常有用。一个示例是标准库中的tails
函数。
tails :: [a] -> [[a]]
tails [] = [[]]
tails xxs@(_:xs) = xxs : tails xs
我想补充一下,@
在所有级别都可用,这意味着你可以这样做:
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 Tuple
,b
只是元组中第一个 Just
,c
和 d
分别是元组中第一个和第二个 Just
中包含的值。
@
符号进行了解释。 - Rob Kennedy