了解与 cons 运算符的模式匹配

发布于 2024-09-01 18:15:45 字数 359 浏览 10 评论 0原文

在“Programming F#”中,我遇到了像这样的模式匹配(我简化了一点):

let rec len list = 
  match list with
  | [] -> 0
  | [_] -> 1
  | head :: tail -> 1 + len tail;;

实际上,我知道最后一个匹配识别列表的头部和尾部。从概念上讲,我不明白它为什么有效。据我了解, :: 是 cons 运算符,它将在列表的头部位置附加一个值,但在我看来,它不像在这里被用作运算符。我是否应该将其理解为列表的“特殊语法”,其中 :: 根据上下文解释为运算符或“匹配模式”?或者可以使用其他运算符将相同的想法扩展到列表以外的类型吗?

In "Programming F#" I came across a pattern-matching like this one (I simplified a bit):

let rec len list = 
  match list with
  | [] -> 0
  | [_] -> 1
  | head :: tail -> 1 + len tail;;

Practically, I understand that the last match recognizes the head and tail of the list. Conceptually, I don't get why it works. As far as I understand, :: is the cons operator, which appends a value in head position of a list, but it doesn't look to me like it is being used as an operator here. Should I understand this as a "special syntax" for lists, where :: is interpreted as an operator or a "match pattern" depending on context? Or can the same idea be extended for types other than lists, with other operators?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

音栖息无 2024-09-08 18:15:46

它用作格式化程序或正式的模式,“list”与三种模式匹配:

[] 表示列表为空

[_] 表示列表只有一个元素,因为你不关心关于元素是什么,所以只需将 _ 放在那里,也可以使用 [a]。

head::tail 意味着列表有两部分:头和尾。

您可以将 F# 模式匹配视为强大的 if then else 结构。

It is used as a formatter or formally pattern, `list' is matched to the three patterns:

[] means the list is empty

[_] means the list has one element, since you don't care about what the element is, so simply put _ there, you can also use [a].

head::tail means that the list does have two parts: a head and a tail.

You can view F# pattern matching as a powerful if then else structure.

池木 2024-09-08 18:15:45

它是列表的特殊语法。因此,您可以将 list 类型视为可区分联合:

type list<'T> =         // '
    | Nil
    | Cons of 'T * list<'T>

除了有特殊语法使 Nil 成为 []缺点(h,t)h::t。那么这只是有区别的联合上的正常模式匹配。这有帮助吗?

(也可以参见此博客条目。)

It is special syntax for lists. You can think of the list type as a discriminated union thusly:

type list<'T> =         // '
    | Nil
    | Cons of 'T * list<'T>

except that there's special syntax that makes Nil be [] and Cons(h,t) be h::t. Then it's just normal pattern matching on a discriminated union. Does that help?

(Possibly see also this blog entry.)

感情洁癖 2024-09-08 18:15:45

除了Brian的回答之外,还有几点值得注意。 h::t 语法既可以用作运算符 ,也可以用作模式

let l = 1::2::[]                    // As an operator
match l with x::xs -> 1 | [] -> 0   // As a pattern

这意味着它是一个有点特殊的构造,因为其他运算符(例如 +) 不能用作模式(用于将结果分解回运算符的参数) - 显然,对于 + 来说,这将是不明确的。

另外,模式 [_] 很有趣,因为它是嵌套模式的示例。它组成:

  • _ - 下划线模式,匹配任何值并且不绑定任何符号
  • [; ] - 单元素列表模式,它匹配具有单个元素的列表,并将列表的元素与嵌套的 匹配。

您还可以使用 | 编写 match 1::[] [x]-> x 将返回单个元素的值(在本例中为 1)。

In addition to Brian's answer, there are a few points that are worth noting. The h::t syntax can be used both as an operator and as a pattern:

let l = 1::2::[]                    // As an operator
match l with x::xs -> 1 | [] -> 0   // As a pattern

This means that it is a bit special construct, because other operators (for example +) cannot be used as patterns (for decomposing the result back to the arguments of the operator) - obviously, for +, this would be ambiguous.

Also, the pattern [_] is interesting, because it is an example of nested pattern. It composes:

  • _ - Underscore pattern, which matches any value and doesn't bind any symbols
  • [ <pattern> ] - Single-element list pattern, which matches a lists with single elements and matches the element of the list with the nested <pattern>.

You could also write match 1::[] with | [x] -> x which would return the value of the single element (in this case 1).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文