关键词";作为「;在SML/NJ

关键词";作为「;在SML/NJ,sml,smlnj,Sml,Smlnj,我最近看到人们在SML/NJ程序中使用as。我找到的最有用的参考资料是 虽然OCaml也属于ML编程语言家族,但它们是不同的。例如,在前面答案中给出的示例程序中 let rec compress = function | a :: (b :: _ as t) -> if a = b then compress t else a :: compress t | smaller -> smaller;; 我把它翻译成SML/NJ是(如果我做错了,请纠正我) 正如您所看到

我最近看到人们在SML/NJ程序中使用
as
。我找到的最有用的参考资料是

虽然OCaml也属于ML编程语言家族,但它们是不同的。例如,在前面答案中给出的示例程序中

let rec compress = function
    | a :: (b :: _ as t) -> if a = b then compress t else a :: compress t
    | smaller -> smaller;;
我把它翻译成SML/NJ是(如果我做错了,请纠正我)

正如您所看到的,模式
(b::u作为t)
的顺序不同于第二个代码段中的
(t作为b::u)
。(尽管如此,它们的用法基本相同)


对于可能的答案,我希望它能够包含(1)在SML/NJ的任何官方文档、课程和书籍中引用此关键字
作为
,以及“可能”(2)一些示例来说明其用法。我希望这个问题能够帮助未来的用户将
视为
关键字
视为
是标准ML定义('97修订版)的一部分。见(我的):

在Haskell和几乎所有其他允许将标识符绑定到(子)模式的语言中,这些被称为模式,但名称的来源显然来自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名称现在位于
as
关键字的右侧,但事实并非如此(请参见下面的组合示例):

还有一个组合示例,您可以看到
as
在记录中的用法与其在其他地方的用法一致,即名称保留在
as
关键字的左侧(此处名称是记录标签)


@约翰克莱曼
as
是1997年SML修订版的一部分。在此处搜索“分层”:或在PDF版本的定义中搜索第79页。@IonuțG.Stan您是对的。出于某种原因,它没有出现在我参考的SML关键字列表中,但我在后续SML的文档中找到了它,所以我认为它是一个扩展。谢谢
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 => ()
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 => ()
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 => ()