问题描述
我定义了2个签名和4个模块,如下所示:
I have defined 2 signature and 4 modules as follows, and it works fine:
module type TRIANGLE =
sig
type 'a t
val get ...
val set ...
...
end
module type MATRIX =
sig
type 'a t
val unionArrayArray: 'a TriangleArray.t -> 'a TriangleArray.t -> 'a t
val unionListList: 'a TriangleList.t -> 'a TriangleList.t -> 'a t
val unionArrayList: 'a TriangleArray.t -> 'a TriangleList.t -> 'a t
val unionListArray: 'a TriangleList.t -> 'a TriangleArray.t -> 'a t
...
end
module rec MatrixArray: MATRIX =
struct
type 'a t = 'a array array
...
end
and MatrixList: MATRIX =
struct
type 'a t = 'a list list
...
end
and TriangleArray: TRIANGLE =
struct
type 'a t = 'a array array
...
end
and TriangleList: TRIANGLE =
struct
type 'a t = 'a list list
...
end
TRIANGLE
和MATRIX
是两个并行签名.函数unionXXXX
取两个直角三角形,如果它们的边长相同,则建立一个矩阵.
TRIANGLE
and MATRIX
are two parallel signatures. The function unionXXXX
takes two right triangles, if their sides have same length, builds a matrix.
模块XXXXArray
在内部由array的数组实现,而模块XXXXList
在内部由list的列表实现.但是它们可能具有相同的签名XXXX
,其中包括诸如set
,get
...
The module XXXXArray
is internally realized by array of array, and the module XXXXList
is internally realized by list of list. But they could have same signature XXXX
which includes such functions as set
, get
...
此设计的问题在于,对于TRIANGLE
的set
,get
之类的功能,4个unionXXXX
函数可以具有相同的实现.我们只需要一个函数union
,它的类型实际上是: 'a TRIANGLE.t -> 'a TRIANGLE.t -> 'a MATRIX.t
.
The problem of this design is that, with the functions like set
, get
of TRIANGLE
, 4 unionXXXX
functions can have same implementation. We just need one function union
, and its type is actually : 'a TRIANGLE.t -> 'a TRIANGLE.t -> 'a MATRIX.t
.
但是,如果我按以下方式定义签名MATRIX
,则编译器将在union
的签名处停止并给出Error: Unbound module Triangle
:
But if I define the signature MATRIX
as follows, the compiler stops at the signature of union
and gives an Error: Unbound module Triangle
:
module type TRIANGLE =
sig
type 'a t
val get ...
val set ...
...
end
module type MATRIX =
sig
type 'a t
val union: 'a TRIANGLE.t -> 'a TRIANGLE.t -> 'a t
...
end
我希望我已经展示了将4个unionXXXX
函数合并为一个union
更好,但是很遗憾我们不能指定其类型,因为缺少'a TRIANGLE.t
,或者签名MATRIX
或模块MatrixXXXX
中.
I hope I have shown it is better to combine 4 unionXXXX
functions to one union
, but it is really a pity that we can't specify its type, because of the lack of 'a TRIANGLE.t
, either in the signature MATRIX
or in the modules MatrixXXXX
.
我希望我的需求和关注已得到清晰描述,有人能找到解决方案或更好的设计吗?
I hope my need and concern has been clearly described, and does anyone have a solution or a better design?
Edit1 :根据评论的建议更改字母大小写...
Edit1 : change case of letters as the comment suggests...
推荐答案
首先,请遵循约定:通常期望模块名称具有CamelCase
格式,而模块类型名称具有ALL_UPPERCASE
格式.我花了两遍才知道您正在处理模块类型而不是模块.
First, a word on conventions : it's usually expected that module names have CamelCase
formatting and module type names have ALL_UPPERCASE
formatting. It took me two reads to notice you were dealing with module types instead of modules.
因此,您在这里要说的是,对于实现TRIANGLE
的任何模块Triangle
,任何实现模块类型MATRIX
的模块都应该能够提供以下签名:
So, what you are trying to say here is that any module which implements module type MATRIX
should be able, for any module Triangle
that implements TRIANGLE
, provide this signature:
type 'a t
val union : 'a Triangle.t -> 'a Triangle.t -> 'a t
不可能这样表达通用量词.您应该做的是使用一个存在量词和一个仿函数:
It's not possible to express universal quantifiers like that. What you should do is use an existential quantifier and a functor :
module type MATRIX = sig
module Triangle : TRIANGLE
type 'a t
val union : 'a Triangle.t -> 'a Triangle.t -> 'a t
end
module MatrixOfTriangle = functor (Triangle:TRIANGLE) -> struct
module Triangle = Triangle
type 'a t = ...
let union t1 t2 = ...
end
这确实迫使您指定在代码的任何给定点上正在处理的三角形,但是可以将函子与TRIANGLE
参数一起使用,以避免建立在一种三角形上.
This does force you to specify what triangle you are working on at any given point in your code, but you can use functors with TRIANGLE
arguments to avoid settling on one type of triangle.
这篇关于是否需要具有签名类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!