我最近看到人们as在他们的SML/NJ计划中使用.我找到的最有用的参考是OCaml中的"as"关键字.
虽然OCaml也属于ML编程语言家族,但它们是不同的.例如,在上一个答案中给出的示例程序中,
let rec compress = function
| a :: (b :: _ as t) -> if a = b then compress t else a :: compress t
| smaller -> smaller;;
Run Code Online (Sandbox Code Playgroud)
我对SML/NJ的翻译是(如果我做错了,请纠正我)
fun compress (a :: (t as b :: _)) = if a = b then compress t else a :: compress t
| compress smaller = smaller
Run Code Online (Sandbox Code Playgroud)
如您所见,该模式(b :: _ as t)的顺序(t as b :: _)与第二个代码段不同.(尽管如此,它们的用法几乎相同)
对于潜在的答案,我希望它可以包含(1)as在SML/NJ的官方文档,课程和书籍中的任何一个中引用该关键字,以及"可能"(2)一些示例来说明其用法.我希望这个问题可以帮助未来的用户看到as.
该as关键字是标准ML定义(97修订版)的一部分.见第79页,图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 => ()
Run Code Online (Sandbox Code Playgroud)
其他用法出现在记录模式中.请注意,乍一看,它可能给人的印象是,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 => ()
Run Code Online (Sandbox Code Playgroud)
还有一个组合示例,您可以在其中看到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 => ()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
786 次 |
| 最近记录: |