Функтор, включающий наследование модулей, не работает - PullRequest
2 голосов
/ 31 января 2012

Я все еще борюсь с моим дизайном и реализацией модулей, я определил следующее:

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 Ответ

4 голосов
/ 31 января 2012

Вы принудительно задали сигнатуру вашего функтора AMatrixArrayFun:

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

Запись этого слова исключает любые связи типов между возвращаемыми модулями и аргументом Mmm и Matrix.OCaml разрешено только знать, что это AMATRIX, но не то, что его подмодуль Matrix на самом деле был модулем Matrix, переданным в качестве аргумента функтора.

Вам необходимо добавить эту информацию в подпись функтора:

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