我仍然在努力设计和实施,认为它的进展......
首先,我定义了2个基本签名和2个模块:
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
然后我定义了3个签名,3个仿函数,并将它们应用于上面的基本模块:
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)
实际上我需要定义一个函数f: AreaMmmArray.t -> ViDbmArray.t -> AreaMmmArray.t * ViDbmArray.t
,它需要另一个函数g: 'a Mmm.t -> 'a Matrix.t -> 'a Mmm.t * 'a Matrix.t
。因为它涉及几个并行模块的类型,我的主要问题是我应该在哪些模块中定义它们。
在上面的代码中,我尝试了f
中的ViDbmFun
和g
中的AMatrixFun
。汇编在(AMatrixArray.g mmm dbm);
停止并给我:
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
我认为该错误是合理的,因为int Mmm.t
中的AreaMmmFun
可能不是MmmArray.t
强制AMatrixArray
... ...是否有办法解决此问题?
同样,我认为主要问题是定义f
和g
的位置,有人可以帮忙吗?
答案 0 :(得分:1)
我不确定您要实现的目标,但正如您所说,引用AMatrix
仿函数中的特定AreaMmm
实例没有意义。只有两个解决方案:您需要在AreaMmm
的实例上参数化AMATRIX with module Mmm = Mmm
仿函数,或者您必须在仿函数中构建合适的实例。
答案 1 :(得分:0)
我说你确实没有达到正确的定义水平。 Matrix
和Mmm
是独立的,并汇总成AMatrix. Here you try to define a function that speaks about both
矩阵and
Mmm in a
FooMmmFun functor, which only knows about
Mmm , not
矩阵; using the particular instance
MatrixArray`不是解决方案,尝试执行此操作时会出现类型错误。
您必须在知道f
(或Matrix
)和ViDbm
(或Mmm
)的级别定义AreaMmm
。这是我的建议,在声明AREAMMM
签名后添加到您的代码中。它主要为AMatrix
定义了一个functorized图层,就像您对Matrix
和MMM
所做的那样。
(* does not speak about `f` as no `Matrix` is available *)
module AreaMmmFun (Mmm: MMM) : AREAMMM with module Mmm = Mmm = struct
module Mmm = Mmm
type t = | Mtop | Mbot | M of int Mmm.t
end
module AreaMmmArray = AreaMmmFun(MmmArray)
(* a functor over `AMatrix`, that knows both `Matrix` and `Mmm`,
so we can define `f` here. I don't know which signature you want. *)
module AMatrixFun (AMatrix : AMATRIX)
= struct
module ViDbm = ViDbmFun(AMatrix.Matrix)
module AreaMmm = AreaMmmFun(AMatrix.Mmm)
let f (am: AreaMmm.t) (vd: ViDbm.t) : AreaMmm.t * ViDbm.t =
let (AreaMmm.M mmm), (ViDbm.D dbm) = am, vd in
(AMatrix.g mmm dbm);
failwith "to do"
end
module AmatrixFooArray = AMatrixFun(AMatrixArray)
PS:您可以为顶部/底部关闭的类型定义参数类型,以避免重复构造函数名称。在任何模块之外:
type 'a order = Top | Bot | D of 'a
然后,您可以将VIDBM.t
定义为int Matrix.t order
,将AREAMMM.t
定义为int Mmm.t order
,而不是将两个不兼容的类型和系列的构造函数定义为Mtop
,{ {1}} ...)。