在“编程F#”中,我遇到了像这样的模式匹配(我简化了一点):
let rec len list =
match list with
| [] -> 0
| [_] -> 1
| head :: tail -> 1 + len tail;;
实际上,我知道最后一个匹配会识别列表的头部和尾部。从概念上讲,我不明白为什么它有效。据我所知,::是cons运算符,它在列表的头部位置附加一个值,但它并不像我在这里被用作运算符。我应该将其理解为列表的“特殊语法”,其中::根据上下文被解释为运算符或“匹配模式”吗?或者可以使用其他运算符为列表以外的类型扩展相同的想法吗?
答案 0 :(得分:13)
这是列表的特殊语法。你可以将list
类型视为一个有区别的联盟:
type list<'T> = // '
| Nil
| Cons of 'T * list<'T>
除了有特殊语法使Nil
为[]
且Cons(h,t)
为h::t
。然后它就是一个有区别的联合的正常模式匹配。这有帮助吗?
(可能还会看到this blog entry。)
答案 1 :(得分:10)
除了Brian的回答,还有一些值得注意的地方。 h::t
语法可以用作运算符和作为模式:
let l = 1::2::[] // As an operator
match l with x::xs -> 1 | [] -> 0 // As a pattern
这意味着它是一个有点特殊的构造,因为其他运算符(例如+
)不能用作模式(用于将结果分解回运算符的参数) - 显然,对于{{1这将是模棱两可的。
此外,模式+
很有趣,因为它是嵌套模式的一个示例。它组成:
[_]
- 下划线模式,匹配任何值且不绑定任何符号_
- 单元素列表模式,它匹配具有单个元素的列表,并将列表元素与嵌套[ <pattern> ]
匹配。您还可以编写<pattern>
,它将返回单个元素的值(在本例中为1)。
答案 2 :(得分:2)
它用作格式化程序或正式pattern
,“list”与三种模式匹配:
[]表示列表为空
[_]表示列表中有一个元素,因为你不关心元素是什么,所以只需将_放在那里,你也可以使用[a]。
head :: tail意味着列表有两个部分:头部和尾部。
您可以将F#模式匹配视为强大的if then else结构。