【问题标题】:modular programming in ocamlocaml 中的模块化编程
【发布时间】:2012-07-29 00:06:45
【问题描述】:

我在处理 ocaml 项目时发现了一些我不太了解的东西。

假设我同时使用 OCaml 标准库的 ArrayList 模块。它们都实现了函数length,但类型不同。 在List 模块中,这是它的类型:

length: a' list -> int

Array 模块中,它的类型为:

length: a' array -> int

但是我希望你通过 open 关键字在我正在实现的同一个模块中使用这两个模块:

open List
open Array

当我尝试在列表中使用length 函数时,在编译过程中出现类型错误。
由于 OCaml 是一种强大的静态类型语言,我想知道为什么编译器不知道我想要 list 模块的 length 函数,因为我声明我同时使用了这两个模块。

【问题讨论】:

  • “我想知道为什么编译器不知道我想要 list 模块的长度函数,因为我声明我同时使用两者”是的,但是 fun s -> length s 的类型是什么那么这个上下文呢?
  • 根据 jrouquie 的回答,应该是a' array -> int
  • 没错,但是在假设的 OCaml 编译器试图猜测的情况下,在 OCaml 类型系统中不会有一个最通用的函数类型。你可能对 Haskell 的解决方案感兴趣,输入类:haskell.org/tutorial/classes.html
  • @PascalCuoq:你可以用函子和模块类型做 Haskell 在 OCaml 中所做的事情,除了你必须手动指定类型类的实例而不是被推断

标签: types module namespaces ocaml


【解决方案1】:

OCaml 不会根据函数类型选择一个函数或另一个函数。

当你写作时

open Array

模块Array 的功能正在屏蔽模块List 的同名功能。 当您稍后调用函数length 时,OCaml 会查找名为length 的函数,找到Array.length,并抱怨此函数没有兼容的类型。

通常的方法是调用List.length(而不仅仅是length),如果这是您需要的功能。


更一般地说,OCaml 没有名称重载(即具有两个具有相同名称但参数类型不同的函数或运算符),特别是因为这会使类型推断变得更加困难。

【讨论】:

  • 另外:尽量避免打开模块——这会使阅读代码变得更加困难,因为读者必须记住哪些模块是打开的(以及打开的顺序);同样作为读者,您不会立即意识到函数来自哪里(来自哪个打开的模块)。
  • 我想补充一点,如果使用的值/函数的来源保持清晰,则打开模块很好。所以不要打开像 List 或 Array 这样的模块,它们提供了具有通用名称的函数,但是“打开 Printf”是完全可以的,因为它提供了 printf、fprintf 等函数,其来源是显而易见的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
  • 2016-06-23
  • 2015-11-02
  • 2015-10-03
相关资源
最近更新 更多