Types 由函子构造的两个模之间的类型关系
我定义了几个签名和模块,如下所示:Types 由函子构造的两个模之间的类型关系,types,module,ocaml,functor,Types,Module,Ocaml,Functor,我定义了几个签名和模块,如下所示: module type MATRIX = sig type 'a t val init: 'a -> 'a t end module type MMM = sig type 'a t end module type AMATRIX = sig include MATRIX module Mmm : MMM module Matrix: MATRIX val mmm_of_amatrix: 'a t -> int -&
module type MATRIX =
sig
type 'a t
val init: 'a -> 'a t
end
module type MMM =
sig
type 'a t
end
module type AMATRIX =
sig
include MATRIX
module Mmm : MMM
module Matrix: MATRIX
val mmm_of_amatrix: 'a t -> int -> int -> 'a Mmm.t
end
module type AREAMMM =
sig
type t
module Mmm: MMM
val make: int Mmm.t -> t
end
module MatrixArray: MATRIX =
struct
type 'a t = 'a array array
let init (e: 'a) : 'a t = failwith "to do"
end
module MmmArray: MMM =
struct
type 'a t = 'a array array
end
和两个函子:
module AMatrixFun: functor (Mmm: MMM) -> functor (Matrix: MATRIX) -> AMATRIX
with
module Mmm = Mmm
and
module Matrix = Matrix =
functor (Mmm: MMM) -> functor (Matrix: MATRIX) ->
struct
include MatrixArray
module Mmm = Mmm
module Matrix = Matrix
let mmm_of_amatrix (m: 'a t) (nr_i: int) (nc_i: int) : 'a Mmm.t = failwith "to do"
end
module AreaMmmFun : functor (Mmm: MMM) -> AREAMMM
with module Mmm = Mmm =
functor (Mmm: MMM) ->
struct
type t
module Mmm = Mmm
let make (x: int Mmm.t) : t = failwith "to do"
end
和带有某些模的应用函子:
module AMatrix = AMatrixFun(MmmArray)(MatrixArray)
module AreaMmm = AreaMmmFun(MmmArray)
let a = AMatrix.mmm_of_amatrix (AMatrix.init 5) 0 0
let b = AreaMmm.make a
编译在这段代码上运行良好。但是,如果我将最后一部分更改为
module AMatrix : AMATRIX = AMatrixFun(MmmArray)(MatrixArray)
module AreaMmm : AREAMMM = AreaMmmFun(MmmArray)
let a = AMatrix.mmm_of_amatrix (AMatrix.init 5) 0 0
let b = AreaMmm.make a
编译在最后一行停止,并给出:
File "lib/tools.ml", line 69, characters 21-22:
Error: This expression has type int AMatrix.Mmm.t
but an expression was expected of type int AreaMmm.Mmm.t
我真的想将
:AMATRIX
添加到AMATRIX
中,并将:AREAMMM
添加到AREAMMM
,因为这样可以确保这两个模块受这两个签名的约束。有人能帮忙吗?我仍然不知道您试图实现什么,但是如果您的目标是在模块之间实现某种类型的继承(正如您在前面的某个线程标题中所说的),您可能需要使用递归模块
例如,您可以从定义模块层次结构开始:这里S
是初始模块签名,可以通过S1
和S2
进行扩展:
module type S = sig
type 'a t
end
module type S1 = sig
include S
val f: 'a -> 'a t
end
module type S2 = sig
include S
val g: 'a t -> 'a
end
module Concrete = struct
type 'a t = 'a array
let f a = [| a |] (* fill with the right contents *)
let g a = a.(0) (* fill with the right contents *)
end
然后,创建具体的实现,它准确地定义了什么是'a t
,并实现了S1
和S2
所需的所有功能:
module type S = sig
type 'a t
end
module type S1 = sig
include S
val f: 'a -> 'a t
end
module type S2 = sig
include S
val g: 'a t -> 'a
end
module Concrete = struct
type 'a t = 'a array
let f a = [| a |] (* fill with the right contents *)
let g a = a.(0) (* fill with the right contents *)
end
然后,通过使用正确的签名约束实现,抽象出类型'at
。这里需要递归模块(注意rec
关键字):
您可以测试您的结果:
let a = I2.g (I1.f 0)
它会按预期返回
0
。我仍然不知道您试图实现什么,但是如果您的目标是在模块之间实现某种类型的继承(如您在前面的某个线程标题中所述),您可能需要使用递归模块
例如,您可以从定义模块层次结构开始:这里S
是初始模块签名,可以通过S1
和S2
进行扩展:
module type S = sig
type 'a t
end
module type S1 = sig
include S
val f: 'a -> 'a t
end
module type S2 = sig
include S
val g: 'a t -> 'a
end
module Concrete = struct
type 'a t = 'a array
let f a = [| a |] (* fill with the right contents *)
let g a = a.(0) (* fill with the right contents *)
end
然后,创建具体的实现,它准确地定义了什么是'a t
,并实现了S1
和S2
所需的所有功能:
module type S = sig
type 'a t
end
module type S1 = sig
include S
val f: 'a -> 'a t
end
module type S2 = sig
include S
val g: 'a t -> 'a
end
module Concrete = struct
type 'a t = 'a array
let f a = [| a |] (* fill with the right contents *)
let g a = a.(0) (* fill with the right contents *)
end
然后,通过使用正确的签名约束实现,抽象出类型'at
。这里需要递归模块(注意rec
关键字):
您可以测试您的结果:
let a = I2.g (I1.f 0)
它按预期返回0
。您的应用程序需要知道AMatrix.Mmm.t
与AreaMmm.Mmm.t
相同,因为否则您将无法在另一个模块提供的函数中使用一个模块创建的值
如前所述,如果您断言module AMatrix:AMatrix
,则您将丢弃AMatrix
中未包含的有关AMatrix
内容的任何附加信息。特别是,由于AMATRIX
没有提到AMATRIX.Mmm.t
与AreaMmm.Mmm.t
相同,因此信息丢失,代码无法编译
你应该强调的是:
module AMatrix : AMATRIX
with module Mmm = MmmArray
and module Matrix = MatrixArray
您的应用程序需要知道AMatrix.Mmm.t
与AreaMmm.Mmm.t
相同,因为否则您将无法在另一个模块提供的函数中使用一个模块创建的值
如前所述,如果您断言module AMatrix:AMatrix
,则您将丢弃AMatrix
中未包含的有关AMatrix
内容的任何附加信息。特别是,由于AMATRIX
没有提到AMATRIX.Mmm.t
与AreaMmm.Mmm.t
相同,因此信息丢失,代码无法编译
你应该强调的是:
module AMatrix : AMATRIX
with module Mmm = MmmArray
and module Matrix = MatrixArray
再一次,和另一个线程中的问题一样:你想解决什么问题。请使用文字而不是代码。为了做一些琐碎的事情,我觉得你的代码太复杂了,所以如果你想得到一些帮助,请试着解释清楚你的问题是什么。好吧,我的代码的目的真的不是琐碎的,很难像这样解释它的具体含义。。。所以实现看起来很复杂是正常的。。。但是我认为代码的技术问题对于熟悉函子和模块的人来说是可以理解的……同样,在另一个线程中,同样的问题是:您试图解决什么问题。请使用文字而不是代码。为了做一些琐碎的事情,我觉得你的代码太复杂了,所以如果你想得到一些帮助,请试着解释清楚你的问题是什么。好吧,我的代码的目的真的不是琐碎的,很难像这样解释它的具体含义。。。所以实现看起来很复杂是正常的。。。但是我认为代码的技术问题对于熟悉函子和模的人来说是可以理解的…谢谢你的回答,如果我想强制输入
I1
和I2
到int-array
?我已将中的类型“at=”a数组
更改为'a t=int数组
,但它不起作用…您不能直接这样做,因为I1
满足签名S1
'ai1.t
(其中t
是抽象的)不能与int数组
统一。但是,如果您愿意,您可以定义别名type tt=int I1.t
并在签名中使用别名tt
,但不能用array
替换I1.t
,因为这会破坏抽象:如果其他人使用列表等实现了S
的具体实现呢?谢谢您的回答,如果我想将I1
和I2
中的类型强制为int-array
,该怎么办?我已将中的类型“at=”a数组
更改为'a t=int数组
,但它不起作用…您不能直接这样做,因为I1
满足签名S1
<代码>'a I1.t
(其中t