Определить рекурсивные подписи для модулей

Я знаю, что можно определить рекурсивные модули, кто-нибудь знает, как определить рекурсивные подписи? Например, я хотел бы понять:

module type AAA = sig
  module Bbb : BBB
  type 'a t 
  val f : 'a Bbb.t -> 'a t
end

module type BBB = sig
  module Aaa : AAA
  type 'a t 
  val g : 'a Aaa.t -> 'a t
end

Может ли кто-нибудь помочь?


person SoftTimur    schedule 30.01.2012    source источник


Ответы (2)


Вы не можете, насколько я могу судить. Ближайшее решение - ограничить "рекурсивные" биты тем, что действительно необходимо для выражения каждой подписи отдельно:

module type AA =
sig
  module B : sig type t end
  type t
  val f : unit -> B.t
end

module type BB =
sig
  module A : sig type t end
  type t
  val g : unit -> A.t
end

А затем уточните, когда вы определяете модули:

module rec A : AA with module B = B =
struct
  module B = B
  type t = int
  let f () = B.g ()
end
and B : BB with module A = A =
struct
  module A = A
  type t = int
  let g () = A.f ()
end

FWIW, можно подумать, что можно выразить рекурсивные подписи (с большим количеством повторений) с помощью рекурсивных модулей:

module rec AA :
sig
  module type T = sig module B : BB.T end
end =
struct
  module type T = sig module B : BB.T end
end
and BB :
sig
  module type T = sig module A : AA.T end
end =
struct
  module type T = sig module A : AA.T end
end

Однако это не работает:

Error: Unbound module type BB.T
person Andreas Rossberg    schedule 30.01.2012
comment
Спасибо за ответ... the closest solution is to limit the "recursive" bits ==> Не могли бы вы подробнее рассказать об ограничениях вашего решения? - person SoftTimur; 31.01.2012
comment
Ну, это не позволяет вам выразить произвольную рекурсию между подписями, потому что вам нужно иметь возможность изолировать автономное подмножество каждой подписи как своего рода предварительное объявление. Кроме того, вы повторяете каждое из этих подмножеств в двух местах, но здесь может помочь именование и include-обозначение. В своем ответе я не стал этого делать, потому что соответствующие подмножества (типа t) достаточно малы. - person Andreas Rossberg; 31.01.2012

Вы можете написать что-то вроде этого:

module rec Aaa : sig
  type 'a t 
  val f : 'a Bbb.t -> 'a t
end = Aaa
and Bbb : sig
  type 'a t
  val g : 'a Aaa.t -> 'a t
end = Bbb
person cago    schedule 30.01.2012
comment
Спасибо за ваш комментарий, но я очень хочу дать имя подписи, например, AAA или BBB... вы не упомянули об этом в своем ответе... - person SoftTimur; 30.01.2012