module - OCaml 中的类型共享 - 类型检查器错误

标签 module functional-programming ocaml functor

编译这个程序时:

module type Inc =
    sig
        type t
        val inc : t -> t
    end

module type Dec = 
    sig
        type t
        val dec : t -> t
    end

module Merger (I : Inc) (D : Dec with type t = I.t) =
    struct
        let merge x = x |> I.inc |> D.dec
    end

module IntInc : Inc = 
    struct
        type t = int
        let inc x = x + 10
    end

module IntDec : Dec = 
    struct 
        type t = int
        let dec x = x - 8
    end

module Combiner = Merger (IntInc) (IntDec)

我收到以下错误:

File "simple.ml", line 30, characters 35-41:
Error: Signature mismatch:
       Modules do not match:
         sig type t = IntDec.t val dec : t -> t end
       is not included in
         sig type t = IntInc.t val dec : t -> t end
       Type declarations do not match:
         type t = IntDec.t
       is not included in
         type t = IntInc.t
       File "simple.ml", line 13, characters 38-50: Expected declaration
       File "simple.ml", line 9, characters 13-14: Actual declaration

我认为 D : Dec with type t = I.t 约束将确保 D.t = I.t。为什么不是这样?

更有趣的是,当我删除 module Combiner = Merger (IntInc) (IntDec) 行时,它编译没有错误。

我的问题是:我做错了什么?

最佳答案

您对带有约束的 Merger 的定义是完全正确的,这就是该部分编译没有错误的原因。

如您所说,唯一未编译的部分是 module Combiner = Merger (IntInc) (IntDec)。这是因为,据 OCaml 所知,不满足约束 IntInt.t = IntDec.t。原因是 OCaml 不知道 IntInt.tIntDec.tint。它只知道 IntInt : IncIntDec : Dec - 其他一切都是模块的私有(private)细节。

要解决此问题,您可以将模块的 header 更改为 IntInt : (Inc with type t = int)IntDec : (Dec with type t = int),使类型 t 成为模块公共(public)接口(interface)的一部分而不是私有(private)细节,允许 OCaml 在解析 Merger 仿函数的约束时使用该信息。

关于module - OCaml 中的类型共享 - 类型检查器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27295630/

相关文章:

compiler-construction - 仅将环境的相关子集传递给 eval 的方案解释器

hash - 基于物理身份的替代Hashtbl.hash

emacs - Ocaml - Emacs 图阿雷格模式

Ocaml 元组类型误解

ruby - 如何从扩展类或包含的模块中的类方法访问父类的字符串名称

module - 我可以只从 F# 模块导入一个声明吗?

c - Linux内核 - 从其他模块调用函数时的上下文切换?

Python: pickle 模块的替代方法

haskell - 在 Haskell 的类型声明中符号 `!` 是什么意思?

scala - 我可以在 Scala 中将两个以上的列表压缩在一起吗?