A functor including an inheritance of modules does not work

♀尐吖头ヾ 提交于 2019-12-11 01:39:08

问题


I am still struggling with my design and implementation of modules, I have defined the following:

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

And a functor with an inheritance of modules:

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)

The compilation stop at the last line, and gives an error:

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

So it seems that the compiler does not recognize that int AMatrixArrayFun(MmmArray)(MatrixArray).Matrix.t is actually 'a MatrixArray.t, but this is exactly what a functor is meant to do, right? Maybe it is the inheritance of modules which complicates the thing?

Could anyone help?


回答1:


You have coerced the signature of your AMatrixArrayFun functor to be:

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

Writing this eliminates any type relationships between the returned modules and the Mmm and Matrix argument. OCaml is only allowed to known that it's an AMATRIX, but not that its Matrix submodule was actually the Matrix module passed as a functor argument.

You need to add this information to the functor signature :

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


来源:https://stackoverflow.com/questions/9082514/a-functor-including-an-inheritance-of-modules-does-not-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!