Inheritance 模块及其类型的继承

Inheritance 模块及其类型的继承,inheritance,types,module,ocaml,Inheritance,Types,Module,Ocaml,我定义了2个签名和2个模块,如下所示。一个签名源于另一个签名;一个模块派生自另一个模块 module type MATRIX = sig type 'a t ... end module type AMATRIX = sig include MATRIX ... end module MatrixArray : MATRIX = struct type 'a t = 'a array array ... end module AMatrixArray : AMAT

我定义了2个签名和2个模块,如下所示。一个签名源于另一个签名;一个模块派生自另一个模块

module type MATRIX =
sig
  type 'a t
  ...
end

module type AMATRIX = 
sig
  include MATRIX
  ...
end

module MatrixArray : MATRIX =
struct
  type 'a t = 'a array array
  ...
end

module AMatrixArray : AMATRIX =
struct
  include MatrixArray
  let init (x: 'a) : 'a t =
    Array.make 2 (Array.make 2 x)
  ...
end
但是当我编译它时,它在最后给了我一个错误
错误:这个表达式的类型是'a array array,但是一个表达式的类型应该是'a t='a MatrixArray.t

有人知道我如何保持这个继承并使类型
'at='成为一个数组
被识别吗?

在代码中:

module MatrixArray : MATRIX = struct
  type 'a t = 'a array array
 ...
end
您可以强制
MatrixArray
隐藏
'a t
的定义。解决问题的一种方法是删除签名约束:

module MatrixArray = struct
  type 'a t = 'a array array
 ...
end

当你想抽象类型
t
时,你可以用
(MatrixArray:MATRIX)
替换
MatrixArray
:实际上,
MatrixArray
不仅仅是一个
矩阵,它是一个
矩阵,其中类型
t
的实现是一个数组。所以你可以写:

module MatrixArray : MATRIX with type 'a t = 'a array array =
struct
  type 'a t = 'a array array
  ...
end

这样,您就保留了
矩阵
约束,可以检测类型错误,还可以保留关于类型实际是什么的信息——当然,假设您关心将类型公开而不是抽象

小心放置太多的抽象:隐藏类型(即使用抽象类型)很好,但是OCaml编译器使用清单类型来执行一些优化。抽象类型将阻止编译器执行它们

在您的例子中可能会有一个有趣的例子,即OCaml有两种数组表示形式:标准数组和浮点数的平面数组。如果编译器知道数组中元素的类型,它可以使用正确的表示直接访问数组。但如果元素的类型是抽象的,编译器将添加一个测试来在这两种表示之间进行选择

如果使用浮点数矩阵,则应保留类型清单,以便编译器在访问这些数组时生成最有效的代码

例如:

let init_array t x =
  for i = 0 to Array.length t - 1 do
    t.(i) <- x
  done
让init_数组tx=
对于i=0到Array.length t-1 do

t、 (i)在这种情况下,
矩阵阵列
的类型不再是
矩阵
,我不能再使用
矩阵
来约束
矩阵阵列
。。。这将是一个遗憾,不是吗?您以后仍然可以使用
MATRIX
来约束
MatrixArray
。您只需编写
(MatrixArray:MATRIX)
,而不是简单地编写
MatrixArray
,在那里您需要
t
来抽象我不这么认为。。。如果我在声明
矩阵数组
之后编写
(矩阵数组:矩阵)
,并重新编译代码,它仍然会在函数
init
处停止,并给出相同的错误…当然,因为如果编写
包含(矩阵数组:矩阵)
,那么仍然会抽象类型
t
。在这种情况下,您不希望
t
在调用
Array.make
函数时是抽象的。因此,在这种情况下,只需保留
include MatrixArray
。如果您真的想保持
t
抽象,那么您需要在
矩阵中导出一个构造函数(该构造函数适用于任何类型的
t
),并在
init
中调用该抽象构造函数。
let init_float_array t (x : float) =
  for i = 0 to Array.length t - 1 do
    t.(i) <- x
  done