【问题标题】:In OCaml, why is the list constructor :: not an operator在 OCaml 中,为什么列表构造函数 :: 不是运算符
【发布时间】:2012-11-30 09:59:38
【问题描述】:

我今天正在阅读 Jason Hickey 的在线书籍“Objective Caml 简介”,在关于 Functors 的章节(第 140 页)中,我在 Set functor 的定义中遇到了以下行:

let add = (::)

运行代码导致了一条不太明显的“语法错误”错误消息。在将行中的插件插入 ocaml 顶层后,我发现 :: 实际上不是运算符,而是类型构造函数。

但是,根据我对 Haskell 的了解,等效的 : 构造函数也可以被视为运算符(函数)。

Prelude> :t (:)
(:) :: a -> [a] -> [a]

我的问题是:OCaml 构造函数从来都不是一流的值(暗示书中的代码从一开始就是错误的),为什么会这样?

【问题讨论】:

  • 我通常使用(fun x y -> x :: y) 来解决这个问题(将运算符转换为 lambda)。这有点烦人但有效。此外,即使:: 是一个函数,当您需要交换:: 的参数时,您仍然必须这样做,所以我想这在这方面是有道理的。

标签: list constructor ocaml


【解决方案1】:

在 OCaml 的前身 Caml Light 中,过去构造函数在部分应用时被提升为函数的情况。我不确定为什么在迁移到 OCaml 时会删除此功能,我也对此感到遗憾,但我听到的解释是“没有人使用它”。所以没有List.map Some foo了......

:: 作为代数数据类型构造函数有点特殊,因为它是唯一的中缀构造函数(在解析器中硬编码),但在其他方面的行为与任何其他数据类型构造函数一样。

【讨论】:

  • 我不记得听过“没人用过”的解释。我认为动机是强调函数和构造函数之间的区别......
  • 这很有趣。我正在同时阅读使用 Caml Light 的“函数式编程方法”,并且在几个场合发现该语言比 OCaml 更好(有趣定义的默认模式匹配、let-in-where 表单和内置函数组合运算符)。
  • @camlspotter 不错的发现!为了纠正我之前的评论,“编程的函数方法”一书使用 CAML 而不是我错误地指出的 Caml Light。
猜你喜欢
  • 1970-01-01
  • 2020-08-14
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
  • 1970-01-01
  • 2021-12-04
  • 1970-01-01
  • 2011-01-17
相关资源
最近更新 更多