Более ясная версия этого вопроса была опубликована здесь .
Я определил подпись и два модуля следующим образом. Причина для определения 2-х модулей заключается в том, что я могу использовать MatrixArray
или MatrixList
в зависимости от контекста ...
module type MATRIX =
sig
type 'a t
...
end
module MatrixArray =
(struct
type 'a t = 'a array array
...
end: MATRIX)
module MatrixList =
(struct
type 'a t = 'a list list
...
end: MATRIX)
Затем я определяю другую подпись и еще 2 модуля, которые относятся к MATRIX
, MatrixArray
и MatrixList
:
module type PM =
sig
type 'a t
(* val of_matrix: 'a MatrixArray.t -> 'a t *)
val of_matrix: 'a MATRIX.t -> 'a t
...
end
module PmArray =
(struct
type 'a t = 'a array array
let of_matrix (m: 'a MatrixArray.t) : 'a t =
...
end: PM)
module PmList =
(struct
type 'a t = 'a list list
let of_matrix (m: 'a MatrixList.t) : 'a t =
...
end: PM)
В подписи PM
я могу определить val of_matrix: 'a MatrixArray.t -> 'a t
, но не могу определить val of_matrix: 'a MATRIX.t -> 'a t
(Error: Unbound module MATRIX
). Так что я думаю MATRIX.t
всегда незаконно ...
То, что я действительно хочу реализовать, это ... на уровне подписи, of_matrix: 'a MATRIX.t -> 'a PM.t
, но на уровне модуля PmArray
, of_matrix: 'a MatrixArray.t -> 'a PmArray.t
; на уровне модуля PmList
, of_matrix: 'a MatrixList.t -> 'a PmList.t
.
Я не знаю, нужно ли мне определять дополнительные модули или функторы для реализации этой структуры ... Надеюсь, моя проблема хорошо описана, кто-нибудь может помочь?
Edit1:
Я просто понимаю, что имя of_matrix
может вводить в заблуждение, например, его назвали бы просто f
. Он представляет собой просто функцию типа 'a MatrixArray.t -> 'a PmArray.t
или 'a MatrixList.t -> 'a PmList.t
, ее реализация внутри может быть сложной. И я хотел бы сделать его тип 'a MATRIX.t -> 'a PM.t
, что, к сожалению, не разрешено.
Edit2:
Я бы назвал PM
, например, TRIANGLE
, и назвал бы PmArray
TriagleArray
(что означает треугольник, представленный массивом массива), и назвал бы PmList
TriangleList
(что означает треугольник, представленный списком списка). Учитывая матрицу m
, функция f (m: a MatrixArray.t) : 'a TriangleArray.t
получает свою левую верхнюю половину, разделенную диагональной линией.
На текущем этапе такие функции, как : 'a MatrixArray.t -> 'a TriangleList.t
, на самом деле не нужны, хотя нет причин исключать их позже ... На уровне модуля мне действительно нужны : a MatrixArray.t -> 'a TriangleArray.t
и : a MatrixList.t -> 'a TriangleList.t
, и я просто хотел бы иметь общую подпись / ограничение для них: 'a MATRIX.t -> 'a TRIANGLE.t
где-то.