【问题标题】:why use module type in Ocaml?为什么在 Ocaml 中使用模块类型?
【发布时间】:2018-06-03 20:34:36
【问题描述】:

我对 Ocaml 中的模块类型感到困惑。

我想知道在什么情况下我们应该使用模块类型?

我通常使用 .mli 中的模块 sig 来暴露一些细节,然后把 .ml中对应的实现模块struct。

例如:

.mli

module A:
 sig
   type t = T of string
 end

.ml

module A =
 struct
   type t = T of string
 end

因此,我认为 Ocaml 的模块类似于 C 中的 .h 和 .c 文件。

我知道模块类型可以声明一个接口,但是这个接口和Java的接口一样。

就像书中的一个例子:

open Core.Std

 module type ID = sig
  type t
   val of_string : string -> t
  val to_string : t -> string
 end

  module String_id = struct
   type t = string
    let of_string x = x
    let to_string x = x
  end

  module Username : ID = String_id
  module Hostname : ID = String_id

  type session_info = { user: Username.t;
                  host: Hostname.t;
                  when_started: Time.t;
                }

  let sessions_have_same_user s1 s2 =
       s1.user = s2.host

上述代码有一个错误:它将一个会话中的用户名与另一个会话中的主机进行比较,而这两种情况下都应该比较用户名。

模块类型似乎无法为其实现提供新的通用超类型。

模块类型的真正应用是什么?

【问题讨论】:

    标签: types functional-programming ocaml


    【解决方案1】:

    这里,模块类型用于隐藏类型t给模块的用户。

    当使用Username.tHostname.t 时,不能依赖这些类型是字符串、整数或任何特定类型。模块类型使它们不透明,就好像它们不是模块接口的一部分,而只是一个实现细节,模块编写者将来会改变它。

    基本上,模块的用户只能通过模块函数作用于类型t

    编译器检查用户代码不会对这些类型 t 的实际情况做出任何假设,以便将来模块编写者可以在不破坏用户代码的情况下更改它们。

    【讨论】:

    • 我假设,如果我的目的是隐藏一些细节,模块 sig 就足够了。
    • Username.t 和 Hostname.t 的共同超类型是什么?我假设 Ocaml 不能匹配模块类型。
    • @qc1iu 没有通用的超类型。毕竟,其中一个可能是string,另一个可能是int。作为模块的用户,您无法看到确切的类型是什么,您只能利用模块提供的功能来处理该(抽象)类型。
    【解决方案2】:

    如前所述,这里使用模块类型来实现t 类型的更抽象的视觉。当您将UsernameHostname 定义为两个单独的模块时,这意味着它们在逻辑上必须不同,并且此模块的签名是使用它们的唯一可能方式。

    但你说错了:

    模块类型似乎无法为 它的实现。

    其实你可以明确Username.tHostname.t是同一种类型。

    module Username = (String_id : ID with type t = String_id.t)
    module Hostname = (String_id : ID with type t = String_id.t)
    
    Username.to_string (Hostname.of_string "hi")
    

    这里没用,但有时真的很有帮助。

    【讨论】:

      【解决方案3】:

      module typesfunctors 密切相关。阅读the module system章节。

      函子的参数有一些模块类型,它的结果也有。

      函子被大量使用,大多数标准容器(例如Set-s 或Map-s)都是函子。

      如果您开发通用容器,您肯定会需要仿函数和模块类型。

      (所以函子和模块类型在 Ocaml 中的用处与在 C++ 中的模板一样有用)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-01
        • 2020-04-25
        • 2016-01-14
        • 2022-01-23
        • 1970-01-01
        • 2022-01-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多