Reputation: 5540
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?
Upvotes: 2
Views: 109
Reputation: 24587
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
Upvotes: 4