Version française
Home     About     Download     Resources     Contact us    
Browse thread
Shared types: dependency in modules with polymorphic type
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Hugo Ferreira <hmf@i...>
Subject: Shared types: circular dependency in modules with polymorphic type
Hello,

I have again encountered a problem with sharing types.
However this time I really have a set of interfaces
which need to be "stitched" together via type sharing.

Problem is I am dealing with a circular polymorphic
type dependency. Or at least seems so. I have added the
very simple code for testing at the end. But the short
of it is: with the code below

module Make_P (VI : VB)
               (UI : U)
               (RI : R with type t = UI.t )
= struct

   type instance = UI.instance
   type t = UI.t

   let do_something_nice null =
     let vb0 = VI.empty in
     let vb1 = VI.add vb0 UI.zero in
     RI.do_something_else vb1 UI.one

end

I get the error:

This expression (vb1) has type UI.instance VI.t but is here used with type
   RI.t = UI.t
vb1: UI.instance VI.t


The problem is that VI.t is polymorphic.
And UI uses VI.t setting the polymorphic
type in the process.
I want to make it "UI.instance VI.t."
How can I do that. I have tried:


module Make_P (VI : VB)
               (UI : U with type t = U.instance VI.t)
               (RI : R with type t = UI.t )
and

module Make_P (UI : U)
               (VI : VB with type 'a t = UI.t)
               (RI : R with type t = UI.t )

with no success.



--------------------- Code ---------------



module type VB = sig

   type 'a t

   val empty : 'a t
   val add : 'a t -> 'a -> 'a t
end


module VB1 : VB
= struct

   type 'a t = 'a list

   let empty = []
   let add l e = e :: l
end


module type U =
   sig

     type instance = int
     type t

     val zero : instance
     val one : instance

     val empty : t
     val do_something : t -> instance -> t
end


module Make_U (Vb : VB)
= struct

   type instance = int
   type t = instance Vb.t

   let zero = 0
   let one = 1

   let empty = Vb.empty
   let do_something ts inst = Vb.add ts inst

end


module U1 = Make_U ( VB1 )

let _ =

   let vb0 = VB1.empty in
   let vb1 = VB1.add vb0 U1.zero in
   let vb2 = U1.do_something vb1 U1.one in
   let _ = VB1.add vb2 U1.zero in
   ()


module type R =
   sig

     type instance = int
     type t

     val do_something_else : t -> instance -> t
end

module Make_R (VI : VB)
               (UI : U)
= struct

   type instance = UI.instance
   type t = UI.t

   let do_something_else ts inst = UI.do_something ts inst

end

module R1 = Make_R ( VB1 ) ( U1 )


let _ =

   let vb0 = VB1.empty in
   let vb1 = VB1.add vb0 U1.zero in
   let vb2 = R1.do_something_else vb1 U1.one in
   let _ = VB1.add vb2 U1.zero in
   ()


module Make_P (VI : VB)
               (UI : U)
               (RI : R with type t = UI.t )
= struct

   type instance = UI.instance
   type t = UI.t

   let do_something_nice null =
     let vb0 = VI.empty in
     let vb1 = VI.add vb0 UI.zero in
     RI.do_something_else vb1 UI.one

end

module P1 = Make_P ( U1 ) ( VB1 ) ( R1 )

or

module P1 = Make_P ( VB1 ) ( U1 ) ( R1 )