简体   繁体   English

F#区分联合语法说明

[英]F# discriminated union syntax clarification

I'm reading Expert F# 4.0 and at some point (p.93) the following syntax is introduced for list : 我正在阅读Expert F#4.0 ,在某些时候(第93页),为list引入了以下语法:

type 'T list =
    | ([])
    | (::) of 'T * 'T list

Although I understand conceptually what's going on here, I do not understand the syntax. 尽管我从概念上了解这里发生的事情,但我不了解语法。 Apparently you can put [] or :: between parentheses and they mean something special. 显然,您可以将[]::放在括号之间,它们表示特殊的含义。

Other symbols aren't allowed, for example (++) or (||) . 不允许使用其他符号,例如(++)(||) So what's going on here? 那么这是怎么回事?

And another thing is the 'operator' nature of (::) . 另一件事是(::)的“运算符”性质。 Suppose I have the following (weird) type: 假设我具有以下(怪异)类型:

type 'T X =
    | None
    | Some of 'T * 'T X
    | (::) of 'T * 'T X

Now I can say: 现在我可以说:

let x: X<string> = Some ("", None)

but these aren't allowed: 但是这些是不允许的:

let x: X<string> = :: ("", None)
let x: X<string> = (::) ("", None)

So (::) is actually something completely different than Some , although both are cases in a discriminated union. 因此(::)实际上与Some完全不同,尽管两者都是受歧视的联合体中的情况。

Theoretically, F# spec (see section 8.5) says that union case identifiers must be alphanumeric sequences starting with an upper-case letter. 从理论上讲, F#规范 (请参阅第8.5节)说,联合用例标识符必须是以大写字母开头的字母数字序列。

However, this way of defining list cons is an ML idiomatic thing. 但是,这种定义列表缺点的方法是ML惯用的事情。 There would be riots in the streets if we were forced to write Cons (x, Cons(y, Cons (z, Empty))) instead of x :: y :: z :: [] . 如果我们被迫写Cons (x, Cons(y, Cons (z, Empty)))而不是x :: y :: z :: []就会在街上引起骚动。

So an exception was made for just these two identifiers - ([]) and (::) . 因此,仅对这两个标识符- ([])(::)进行了例外处理。 You can use these, but only these two. 您可以使用这些,但只能使用这两个。 Besides these two, only capitalized alphanumeric names are allowed. 除了这两个以外,仅允许使用大写字母数字名称。

However, you can define free-standing functions with these funny names: 但是,您可以使用以下有趣的名称定义独立功能

let (++) a b = a * b

These functions are usually called " operators " and can be called via infix notation: 这些函数通常称为“ 运算符 ”,可以通过中缀符号来调用:

let x = 5 ++ 6   // x = 30

As opposed to regular functions that only support prefix notation - ie f 5 6 . 与仅支持前缀表示法的常规函数​​(即f 5 6相反。

There is a separate quite intricate set of rules about which characters are allowed in operators, which can be only unary, which can be only binary, which can be both, and how they define the resulting operator precedence. 关于运算符中允许使用哪些字符,有一套非常复杂的规则,它们只能是一元的,只能是二进制的,也可以是两者,以及它们如何定义运算符优先级。 See section 4.1 of the spec or here for full reference. 请参阅规范的4.1节或此处的完整参考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM