定义由仿函数构建的2个并行模块的函数

时间:2012-02-01 19:19:07

标签: types module ocaml functor

我仍然在努力设计和实施,认为它的进展......

首先,我定义了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中的ViDbmFung中的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 ... ...是否有办法解决此问题?

同样,我认为主要问题是定义fg的位置,有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

我不确定您要实现的目标,但正如您所说,引用AMatrix仿函数中的特定AreaMmm实例没有意义。只有两个解决方案:您需要在AreaMmm的实例上参数化AMATRIX with module Mmm = Mmm仿函数,或者您必须在仿函数中构建合适的实例。

答案 1 :(得分:0)

我说你确实没有达到正确的定义水平。 MatrixMmm是独立的,并汇总成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图层,就像您对MatrixMMM所做的那样。

(* 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}} ...)。