OCaml:为什么使用“它们的种类不同"来重命名类型失败? [英] OCaml: Why does renaming a type fail with "Their kinds differ"

查看:68
本文介绍了OCaml:为什么使用“它们的种类不同"来重命名类型失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm building an universal container for for pairs of a type witness and a value of the witnessed type. This I want to use for several different types, which gives me errors because the types are all named the same.

因此,我试图根据这样的函子的结果来重命名类型:

So I'm trying to rename types in the result of a functor like this:

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的类型如何不同?

How can the types of conv and lexeme_conv differ?

推荐答案

您可以通过以下方式替换lexeme_conv的定义来解决该问题:

You can solve the issue by replacing the definition of lexeme_conv by:

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

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

This is due to the fact that type aliases and type definitions do not behave in the same way in regard to destructive substitution. Here for example, with lexeme_conv an alias, the signature will change (since the record definition would stop being exposed), which is forbidden.

这篇关于OCaml:为什么使用“它们的种类不同"来重命名类型失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆