我正在阅读f#代码,我对语法感到困惑。解析器类型介绍如下:
type Parser<'r> = Parser of (char list -> ('r*char list) list)
解释器将其评估为:
type Parser<'r> = | Parser of (char list -> ('r * char list) list)
这对我有意义。然后,引入了一行新的代码:'还需要应用解析器函数,因此我们为它定义了一个部分函数:',以及后面的代码:
let parse (Parser p) = p
,解释器输出为:
Parser<'a> -> (char list -> ('a * char list) list)
我很惊讶这甚至是有效的语法。它是什么,为什么需要它?
非常感谢
答案 0 :(得分:9)
一般
let f
图案 =
体
相当于
let f = function
|
模式 ->
正文
或者,甚至更详细,
let f x =
match x with
|
图案 ->
体
这允许您避免引入一个新的标识符,该标识符会立即被解构,然后再也不会再使用。
在这个特定的例子中,这意味着parse
等同于:
let parse x =
match x with
| Parser p -> p
由于Parser
类型只有一个案例,因此这种解构将永远成功。
答案 1 :(得分:3)
如果您将(char list -> ('r*char list) list)
的类型理解为黑匣子,则可以轻松解释这些类型。
假设我们有一个类型缩写:
type R<'r> = char list -> ('r*char list) list
然后Parser<'r>
可以写成:
type Parser<'r> = Parser of R<'r>
声明函数时:
let parse (Parser p) = p
类型检查器推断类型Parser<'r>
的参数(通过查看Parser p
的结构)。因此,返回值p
显然具有R<'r>
:
val parse : Parser<'a> -> R<'a>
假设用真实的声明代替R<'r>
:
val parse : Parser<'r> -> (char list -> ('r*char list) list)
因此,这里推断的类型完全有意义。