module - OCaml:为什么重命名类型失败并显示 "Their kinds differ"

标签 module ocaml rename functor

我正在为成对的类型见证和见证类型的值构建一个通用容器。我想将其用于几种不同的类型,这会给我带来错误,因为这些类型的名称都相同。

所以我正在尝试重命名仿函数结果中的类型:

module type Witness = sig type 'a key type 'a value end

module type Witnessed = sig
  type 'a key
  type 'a value
  type t
  type ('a, 'b) conv = {
    key : 'c . 'c key -> 'a;
    value : 'c . 'c value -> 'b;
  }
  val box : 'a key -> 'a value -> t
  val conv : ('a, 'b) conv -> t -> ('a * 'b)
end

module MAKE(W : Witness) : Witnessed with type 'a key = 'a W.key
                     and type 'a value = 'a W.value = struct
  include W

  type t = Box : 'a key * 'a value -> t
  let box k v = Box (k, v)
  type ('a, 'b) conv = {
    key : 'c . 'c key -> 'a;
    value : 'c . 'c value -> 'b;
  }
  let conv conv (Box (k, v)) = (conv.key k, conv.value v)
end

type _ token
type _ attrib

module W = struct
  type 'a key = 'a token
  type 'a value = 'a attrib
end

module Boxed = struct
    module T = MAKE(W)
    type lexeme = T.t
    type ('a, 'b) lexeme_conv = ('a, 'b) T.conv
    include (T : module type of T with type 'a key := 'a token
                                  and type 'a value := 'a attrib
                                  and type t := lexeme
                                  and type ('a, 'b) conv := ('a, 'b) lexeme_conv)
end

和 ocaml 说:

File "foo.ml", line 49, characters 38-80:
Error: This variant or record definition does not match that of type
         ('a, 'b) lexeme_conv
       Their kinds differ.

conv 和 lexeme_conv 的类型有何不同?

最佳答案

您可以通过将 lexeme_conv 的定义替换为以下内容来解决此问题:

type ('a, 'b) lexeme_conv = ('a, 'b) T.conv = {
  key : 'c . 'c T.key -> 'a;
  value : 'c . 'c T.value -> 'b;
}

这是因为类型别名和类型定义在破坏性替换方面的行为方式不同。例如,这里使用 lexeme_conv 作为别名,签名将更改(因为记录定义将停止公开),这是被禁止的。

关于module - OCaml:为什么重命名类型失败并显示 "Their kinds differ",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27784768/

相关文章:

c++ - 如何在每个新模块中自动注入(inject)辅助类?

perl - 如何手动安装 XS 模块?

python - 导入目录中的所有模块

file - 将多个不同长度的文件重命名为最后 16 个字符

git gui 应用程序显示检测到的重命名

c - spinlock_irqsave 与死锁

OCaml 坚持函数不是多态的,但不指定类型

ocaml - 在 OCaml 中总结列表的最惯用(或最快)的方法是什么?

mysql - 如何重命名 MySQL 中的主键列?

object - OCaml 对象的多态类型问题