首页 文章

SML / NJ中的关键字“as”

提问于
浏览
2

我最近看到人们在他们的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的官方文档,课程和书籍中的任何一个关键字 as 的引用,以及"maybe"(2)一些例子来说明它的用法 . 我希望这个问题可以帮助未来的用户看到 as .

1 回答

  • 4

    as 关键字是标准ML定义('97修订版)的一部分 . 见page 79, figure 22(突出我的):

    enter image description here

    这些在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 => ()
    

相关问题