F#区别联合语法澄清

Ron*_*erg 4 syntax f# discriminated-union

我正在阅读专家F#4.0,并且在某些时候(第93页)引入了以下语法list:

type 'T list =
    | ([])
    | (::) of 'T * 'T list
Run Code Online (Sandbox Code Playgroud)

虽然我从概念上理解这里发生了什么,但我不理解语法.显然你可以放在括号内[]::之间,它们意味着特别的东西.

其他符号是不允许的,例如(++)(||).那么这里发生了什么?

另一件事是'运营商'的性质(::).假设我有以下(怪异)类型:

type 'T X =
    | None
    | Some of 'T * 'T X
    | (::) of 'T * 'T X
Run Code Online (Sandbox Code Playgroud)

现在我可以说:

let x: X<string> = Some ("", None)
Run Code Online (Sandbox Code Playgroud)

但这些是不允许的:

let x: X<string> = :: ("", None)
let x: X<string> = (::) ("", None)
Run Code Online (Sandbox Code Playgroud)

所以(::)实际上是东西比完全不同Some,虽然两者都是在歧视工会的情况.

Fyo*_*kin 7

从理论上讲,F#规范(参见第8.5节)说联合案例标识符必须是以大写字母开头的字母数字序列.

然而,这种定义列表缺点的方式是ML惯用的东西.如果我们被迫写作Cons (x, Cons(y, Cons (z, Empty)))而不是写作,街上会发生骚乱x :: y :: z :: [].

因此只对这两个标识符做了例外 - ([])(::).你可以使用这些,但只能使用这两个.除了这两个,只允许大写的字母数字名称.

但是,您可以使用以下有趣的名称定义独立功能:

let (++) a b = a * b
Run Code Online (Sandbox Code Playgroud)

这些函数通常称为" 运算符 ",可以通过中缀表示法调用:

let x = 5 ++ 6   // x = 30
Run Code Online (Sandbox Code Playgroud)

与仅支持前缀表示法的常规函数​​相反 - 即f 5 6.

关于运算符中允许哪些字符,有一个单独的非常复杂的规则,这些规则只能是一元的,它们可以只是二元的,可以是两者,以及它们如何定义结果运算符优先级.请参阅规范的4.1节或此处以获取完整参考.