【问题标题】:What does :: and ' mean in oCaml?::和'在oCaml中是什么意思?
【发布时间】:2010-02-27 12:05:53
【问题描述】:

x :: xs' 是什么意思? 我没有太多的功能经验,但是 F# 1 :: 2 :: 3 :: []; 中的 IIRC;创建一个 [1,2,3] 的数组 那么 ' 有什么作用呢?

let rec sum xs =
  match xs with
    | [] -> 0
    | x :: xs' -> x + sum xs'

【问题讨论】:

  • :: 表示 2 个驼峰,' 表示 1 个驼峰!
  • 不错的评论:merd.sourceforge.net/pixel/language-study/… 我不使用 oCaml,但我觉得有一个完整的语法列表很有用,即使没有真正的上下文。
  • 它是一个列表而不是一个数组,它们在函数式编程方面完全不同。

标签: ocaml


【解决方案1】:

我认为 sepp2k 已经回答了大部分问题,但我想补充几点可能会阐明 F#/OCaml 编译器如何解释代码并解释一些常见用途。

关于' 符号 - 这只是名称的一部分(有效标识符以字母开头,然后包含一个或多个字母、数字或' 符号)。如果您的函数或值与其他函数或值非常相似,但在某些方面修改,则通常使用它。

  • 在您的示例中,xs 是一个应该求和的列表,模式匹配分解列表并为您提供一个需要求和的新列表(没有第一个元素),因此它被称为 @ 987654324@

  • 另一个常见的用途是在声明一个实现功能并采用附加参数的本地实用程序函数时(通常在编写尾递归代码时):

    let sum list =
      let rec sum' list res = 
        match list with
        | [] -> res
        | x::xs -> sum' xs (res + x)
      sum' list 0
    

但是,我认为函数/值通常有一个更好的名称,所以我在编写代码时尽量避免使用'(我认为它不是特别可读,而且它不会正确着色堆栈溢出!)

关于:: 符号 - 如前所述,它用于从单个元素和一个列表创建列表(1::[2;3] 创建一个列表[1;2;3])。然而值得注意的是,该符号可以以两种不同的方式使用,编译器也可以以两种不同的方式解释它。

创建列表时,您将其用作构造列表的运算符(就像使用+ 将两个数字相加一样)。但是,当您在 match 构造中使用它时,它被用作 pattern,这是一个不同的语法类别 - 该模式用于将列表 分解 为一个元素和余数,它对任何非空列表都成功:

// operator
let x = 0
let xs = [1;2;3]
let list = x::xs

// pattern
match list with
| y::ys -> // ...

【讨论】:

  • 如果我没记错的话, :: 被称为 cons 运算符。
  • 您忘记声明 sum' 函数递归。另外,匹配后应该有一个in关键字。
  • 谢谢 - 我添加了 rec 关键字。我用 F# 编写代码,它对空格敏感,不需要 in 关键字。
【解决方案2】:

' 只是变量名的一部分。是的foo :: bar,其中 foo 是 a 类型的元素,而 bar 是 a 类型的列表,意思是“以 foo 作为第一个元素的列表,然后是 bar 的元素”。所以match语句的意思是:

如果 xs 是空列表,则值为 0。如果 xs 是包含项 x 后跟 xs' 中的项的列表,则值为 x + sum xs'。由于xxs' 是新变量,因此对于任何非空列表,x 将被分配第一个元素的值,xs' 将被分配包含所有其他元素的列表。

【讨论】:

  • 听起来我可以改写 x :: 余数'。但是 ' 具体是什么意思?那 xs 是一个列表? x::xs 不会有 xs 作为列表的其余部分吗?
  • ' 只是名称中允许的另一个字符。除了最后一个发音为“剩余素数”之外,余数和余数没有区别。
  • @acidzombie24:' 没有任何意义。这只是名字的一部分。你也可以写x :: foo。但是,您不能在代码中写入x :: xs,因为名称xs 已被参数求和。就是这样。
  • 变量中“'”的用法来自学术界喜欢将变量称为x,x'(读作x-prime),f(x),f'(x),等
  • 嗯,你可以写模式x :: xs,只是你将无法再访问那个分支内原来的xs
【解决方案3】:

就像其他人所说的那样,' 是数学的遗留物,其中 x' 将被称为“x 素数”

【讨论】:

    【解决方案4】:

    在 ML 系列语言中,将变量命名为 foo' 以表明它与另一个变量 foo 有某种关联是惯用的,尤其是在像您的代码示例这样的递归中。就像在命令式语言中一样,您使用 ij 作为循环索引。这种命名约定可能有点令人惊讶,因为' 通常是类 C 语言中标识符的非法符号。

    【讨论】:

      【解决方案5】:

      x :: xs' 是什么意思?

      如果您有两个变量名为xxs',那么x :: xs' 会创建一个新列表,其中x 会在xs' 前面添加。

      我没有太多的功能经验,但是 F# 1 :: 2 :: 3 :: []; 中的 IIRC;创建一个 [1,2,3] 的数组

      不完全是。这是一个列表。

      那么 ' 有什么作用?

      它被视为一个字母字符,所以下面是等价的:

      let rec sum xs =
        match xs with
        | [] -> 0
        | x :: ys -> x + sum ys
      

      请注意,:: 在技术上是一个类型构造函数,这就是您可以在模式和表达式中使用它的原因。

      【讨论】:

        猜你喜欢
        • 2011-11-23
        • 2023-04-10
        • 2016-08-26
        • 1970-01-01
        • 2010-12-27
        • 2016-12-17
        • 1970-01-01
        • 1970-01-01
        • 2011-08-12
        相关资源
        最近更新 更多