SML/NJ 中的关键字 "as"
Keyword "as" in SML/NJ
我最近看到有人在他们的 SML/NJ 程序中使用 as
。我找到的最有用的参考是 "as" keyword in OCaml.
虽然OCaml也属于ML编程语言家族,但它们是不同的。比如上一个回答给出的示例程序中,
let rec compress = function
| a :: (b :: _ as t) -> if a = b then compress t else a :: compress t
| smaller -> smaller;;
我翻译成SML/NJ是(如有错误请指正)
fun compress (a :: (t as b :: _)) = if a = b then compress t else a :: compress t
| compress smaller = smaller
如您所见,模式 (b :: _ as t)
的顺序与第二个片段中的 (t as b :: _)
不同。 (尽管如此,它们的用法几乎相同)
对于潜在的答案,我希望它可以包含 (1) 在 SML/NJ、课程和书籍的任何官方文档和 "maybe" 中对这个关键字 as
的引用( 2)一些例子来说明它的用法。我希望这个问题可以帮助未来的用户看到 as
.
as
关键字是标准 ML 定义('97 修订版)的一部分。请参阅 page 79, figure 22(突出显示我的):
这些在 Haskell 和几乎任何其他允许将标识符绑定到(子)模式的语言中称为 as-patterns,但名称的来源显然来自 ML。
它的作用是为模式或模式的一部分命名。例如,我们可以捕获 2 元组列表的整个头部,同时为元组的值分配名称。
fun example1 (list : (int * string) list) =
case list of
(* `head` will be bound to the tuple value *)
(* `i` will be bound to the tuple's 1st element *)
(* `s` will be bound to the tuple's 2nd element *)
head as (i, s) :: tail => ()
| nil => ()
另一种用法出现在记录模式中。请注意,乍一看,它可能给人的印象是 as-name 现在位于 as
关键字的右侧,但事实并非如此(参见下面的组合示例):
fun example2 (list : { foo: int * string } list) =
case list of
(* `f` will be found to the value of the `foo` field in the record. *)
{ foo as f } :: tail => ()
(* The above can also be expressed as follows *)
| { foo = f } :: tail => ()
| nil => ()
还有一个组合示例,您可以看到 as
在记录中的用法与它在其他地方的用法一致,即名称保留在 as
关键字的左侧(这里的名字是唱片公司)。
fun example3 (list : { foo: int * string } list) =
case list of
head as { foo as (i, s) } :: tail => ()
(* This is valid, too, but `foo` is not a binding. *)
| head as { foo = (i, s) } :: tail => ()
(* Here, `f` is bound to the whole tuple value. *)
| head as { foo = f as (i, s) } :: tail => ()
| nil => ()
我最近看到有人在他们的 SML/NJ 程序中使用 as
。我找到的最有用的参考是 "as" keyword in OCaml.
虽然OCaml也属于ML编程语言家族,但它们是不同的。比如上一个回答给出的示例程序中,
let rec compress = function
| a :: (b :: _ as t) -> if a = b then compress t else a :: compress t
| smaller -> smaller;;
我翻译成SML/NJ是(如有错误请指正)
fun compress (a :: (t as b :: _)) = if a = b then compress t else a :: compress t
| compress smaller = smaller
如您所见,模式 (b :: _ as t)
的顺序与第二个片段中的 (t as b :: _)
不同。 (尽管如此,它们的用法几乎相同)
对于潜在的答案,我希望它可以包含 (1) 在 SML/NJ、课程和书籍的任何官方文档和 "maybe" 中对这个关键字 as
的引用( 2)一些例子来说明它的用法。我希望这个问题可以帮助未来的用户看到 as
.
as
关键字是标准 ML 定义('97 修订版)的一部分。请参阅 page 79, figure 22(突出显示我的):
这些在 Haskell 和几乎任何其他允许将标识符绑定到(子)模式的语言中称为 as-patterns,但名称的来源显然来自 ML。
它的作用是为模式或模式的一部分命名。例如,我们可以捕获 2 元组列表的整个头部,同时为元组的值分配名称。
fun example1 (list : (int * string) list) =
case list of
(* `head` will be bound to the tuple value *)
(* `i` will be bound to the tuple's 1st element *)
(* `s` will be bound to the tuple's 2nd element *)
head as (i, s) :: tail => ()
| nil => ()
另一种用法出现在记录模式中。请注意,乍一看,它可能给人的印象是 as-name 现在位于 as
关键字的右侧,但事实并非如此(参见下面的组合示例):
fun example2 (list : { foo: int * string } list) =
case list of
(* `f` will be found to the value of the `foo` field in the record. *)
{ foo as f } :: tail => ()
(* The above can also be expressed as follows *)
| { foo = f } :: tail => ()
| nil => ()
还有一个组合示例,您可以看到 as
在记录中的用法与它在其他地方的用法一致,即名称保留在 as
关键字的左侧(这里的名字是唱片公司)。
fun example3 (list : { foo: int * string } list) =
case list of
head as { foo as (i, s) } :: tail => ()
(* This is valid, too, but `foo` is not a binding. *)
| head as { foo = (i, s) } :: tail => ()
(* Here, `f` is bound to the whole tuple value. *)
| head as { foo = f as (i, s) } :: tail => ()
| nil => ()