包含模块继承的仿函数不起作用

时间:2012-01-31 15:51:14

标签: inheritance types module ocaml

我仍然在努力设计和实现模块,我已经定义了以下内容:

module type MATRIX =
sig
  type 'a t
  val init: 'a -> 'a t
  val print: 'a t -> unit
end

module type MMM =
sig
  type 'a t
end

module type AMATRIX =
sig
  include MATRIX
  module Mmm : MMM
  module Matrix: MATRIX
  val matrix_of_amatrix: 'a t -> int -> int -> 'a Matrix.t
end

module MatrixArray: MATRIX =
struct
  type 'a t = 'a array array
  let init (e: 'a) : 'a t = failwith "to do"
  let print (x: 'a t) : unit = failwith "to do"
end

module MmmArray: MMM =
struct
  type 'a t = 'a array array
end

还有一个继承模块的仿函数:

module AMatrixArrayFun: functor (Mmm: MMM) -> functor (Matrix: MATRIX) -> AMATRIX =
  functor (Mmm: MMM) ->
    functor (Matrix: MATRIX) ->
struct
  include MatrixArray
  module Mmm = Mmm
  module Matrix = Matrix

  let matrix_of_amatrix (m: 'a t) (nr_i: int) (nc_i: int) : 'a Matrix.t = failwith "to do"
end

module AMatrixArray = AMatrixArrayFun(MmmArray)(MatrixArray)

let () =  MatrixArray.print (AMatrixArray.matrix_of_amatrix (AMatrixArray.init 5) 0 0)

编译在最后一行停止,并给出错误:

Error: This expression has type
         int AMatrixArray.Matrix.t =
           int AMatrixArrayFun(MmmArray)(MatrixArray).Matrix.t
       but an expression was expected of type 'a MatrixArray.t

因此,似乎编译器无法识别int AMatrixArrayFun(MmmArray)(MatrixArray).Matrix.t实际上是'a MatrixArray.t,但这正是仿函数的意图,对吧?也许是模块的继承使事情复杂化了?

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:4)

您强制将AMatrixArrayFun仿函数的签名强制为:

functor (Mmm: MMM) -> functor (Matrix: MATRIX) -> AMATRIX

写这个消除了返回的模块与MmmMatrix参数之间的任何类型关系。 OCaml只允许知道它是AMATRIX,但不是它的Matrix子模块实际上是作为仿函数参数传递的Matrix模块。

您需要将此信息添加到仿函数签名中:

functor (Mmm: MMM) -> functor (Matrix: MATRIX) -> 
  AMATRIX with module Mmm = Mmm and  module Matrix = Matrix