I am still struggling with my design and implementation, thought it progresses…
First, I have defined 2 basic signatures and 2 modules:
module type MATRIX = sig type 'a t end
module MatrixArray: MATRIX = struct
type 'a t = 'a array array
end
module type MMM = sig type 'a t end
module MmmArray: MMM = struct
type 'a t = 'a array array
end
Then I have defined 3 signatures, 3 functors and applied them with the basic modules above:
module type AMATRIX = sig
include MATRIX
module Mmm : MMM
module Matrix: MATRIX
val g: 'a Mmm.t -> 'a Matrix.t -> 'a Mmm.t * 'a Matrix.t
end
module AMatrixFun (Mmm: MMM) (Matrix: MATRIX) : AMATRIX with module Mmm = Mmm and module Matrix = Matrix = struct
include MatrixArray
module Mmm = Mmm
module Matrix = Matrix
let g (mmm: 'a Mmm.t) (dbm: 'a Matrix.t) : 'a Mmm.t * 'a Matrix.t = failwith "to do"
end
module AMatrixArray = AMatrixFun(MmmArray)(MatrixArray)
module type VIDBM = sig
module Matrix: MATRIX
type t = | Dtop | Dbot | D of int Matrix.t
end
module ViDbmFun (Matrix: MATRIX) : VIDBM with module Matrix = Matrix = struct
module Matrix = Matrix
type t = | Dtop | Dbot | D of int Matrix.t
end
module ViDbmArray = ViDbmFun(MatrixArray)
module type AREAMMM = sig
module Mmm: MMM
type t = | Mtop | Mbot | M of int Mmm.t
end
module AreaMmmFun (Mmm: MMM) : AREAMMM with module Mmm = Mmm = struct
module Mmm = Mmm
type t = | Mtop | Mbot | M of int Mmm.t
let f (am: t) (vd: ViDbmArray.t) : t * ViDbmArray.t =
let (M mmm), (ViDbmArray.D dbm) = am, vd in
(AMatrixArray.g mmm dbm);
failwith "to do"
end
module AreaMmmArray = AreaMmmFun(MmmArray)
Actually I need to define a function f: AreaMmmArray.t -> ViDbmArray.t -> AreaMmmArray.t * ViDbmArray.t which requires another function g: 'a Mmm.t -> 'a Matrix.t -> 'a Mmm.t * 'a Matrix.t. As it involves the types of several parallel modules, my major question is in which modules I should define them.
In the code above, as a try, I have implemented f in ViDbmFun and g in AMatrixFun. The compilation stops at (AMatrixArray.g mmm dbm); and gives me:
Error: This expression has type int Mmm.t = int Mmm.t
but an expression was expected of type
'a AMatrixArray.Mmm.t = 'a MmmArray.t
I think the error is reasonable, because int Mmm.t in AreaMmmFun may be something other than MmmArray.t forced in AMatrixArray… Is there a way to work around this?
Again, I think the major question is where to define f and g, could anyone help?
I’d say you are not at the right level of definition indeed.
MatrixandMmmare independent, and put together to make anAMatrix. Here you try to define a function that speaks about bothMatrixandMmmin aFooMmmFunfunctor, which only knows aboutMmm, notMatrix; using the particular instanceMatrixArray` is not the solution, and you get a type error trying to do that.You have to define
fat a level that knows about bothMatrix(orViDbm) andMmm(orAreaMmm). Here is my suggestion, to add to your code after the declaration of theAREAMMMsignature. It mostly define a functorized layer forAMatrix, as you did forMatrixandMMM.PS: you could define a parametric type for types closed by top/bottom, to avoid duplication of constructor names. Outside of any module:
Then you can define
VIDBM.tasint Matrix.t order, andAREAMMM.tasint Mmm.t order, instead of having two incompatible types and families of constructors (Mtop,Dtop…).