caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Shared types: dependency in modules with polymorphic type
@ 2009-05-13 19:12 Hugo Ferreira
  2009-05-13 19:40 ` [Caml-list] " Jacques Carette
  0 siblings, 1 reply; 10+ messages in thread
From: Hugo Ferreira @ 2009-05-13 19:12 UTC (permalink / raw)
  To: caml-list

Hello,

I have had to parametrize several modules
an am now having trouble using these interfaces.
I have the following situation:

The following signatures and module are a
generic data container. I want to use
this container in another module.

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


The following interface and module use the
generic container. It also stipulates what
type will be used in the polymorphic type.

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) : U
= 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 )

If I use and access all U1's elements
via its interface I have no problems.

However I need to use VB1 to access and
manipulate the U1.t set in order to
manipulate U1.instance types so...

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

I get errors: all uses of Vb1.t fail. For example
using the first two lines and commenting the
third I get the error:

This expression has type U1.instance VB1.t but is here used with type
   U1.t = Make_U(VB1).t
vb1: U1.instance VB1.t

Or in the case above as is, I get:

This expression has type U1.t = Make_U(VB1).t but is here used with type
   'a VB1.t
vb2: U1.t

My question is: is their any way I may organize the modules or
indicate shared types in order to use a (very extensive) VB
interface (Or VB1 module)? Specifically how do I enforce the
shared type:

  U1.instance VB1.t = U1.t = Make_U(VB1).t

TIA,
Hugo F.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] Shared types: dependency in modules with polymorphic type
  2009-05-13 19:12 Shared types: dependency in modules with polymorphic type Hugo Ferreira
@ 2009-05-13 19:40 ` Jacques Carette
  2009-05-14  7:58   ` Hugo Ferreira
  2009-05-14 11:41   ` Shared types: circular " Hugo Ferreira
  0 siblings, 2 replies; 10+ messages in thread
From: Jacques Carette @ 2009-05-13 19:40 UTC (permalink / raw)
  To: Hugo Ferreira; +Cc: caml-list

One modification which will get you a long way towards your goal is to 
remove the : VB from

Hugo Ferreira wrote:
> module VB1 : VB
> = struct  ...
While this may look like it is just "type checking", it in fact does 
more and makes sure that VB1.t, to the outside world, is abstract.  This 
stops any possibility of unification with 'like' types.  Same with Make_U.

Note that VB1 will still be of type VB, and you can be sure of that 
because the constraint in Make_U's signature will enforce it -- only a 
bit later than at declaration time, at use-time.

> My question is: is their any way I may organize the modules or
> indicate shared types in order to use a (very extensive) VB
> interface (Or VB1 module)? Specifically how do I enforce the
> shared type:
>
>  U1.instance VB1.t = U1.t = Make_U(VB1).t
First, try the above.  It may help.  If it does not, then you will need 
to add explicit sharing constraints.  But which sharing constraints are 
*really* needed will be the ones revealed by first removing the type 
annotations you currently have.

Note that you should not have to re-organize your modules at all to 
achieve this [at least, not in this example].

Jacques


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] Shared types: dependency in modules with polymorphic type
  2009-05-13 19:40 ` [Caml-list] " Jacques Carette
@ 2009-05-14  7:58   ` Hugo Ferreira
  2009-05-14 14:42     ` Andreas Rossberg
  2009-05-14 11:41   ` Shared types: circular " Hugo Ferreira
  1 sibling, 1 reply; 10+ messages in thread
From: Hugo Ferreira @ 2009-05-14  7:58 UTC (permalink / raw)
  To: Jacques Carette; +Cc: caml-list

Hi Jacques,

Jacques Carette wrote:
> One modification which will get you a long way towards your goal is to 
> remove the : VB from
> 
> Hugo Ferreira wrote:
>> module VB1 : VB
>> = struct  ...
> While this may look like it is just "type checking", it in fact does 
> more and makes sure that VB1.t, to the outside world, is abstract.  This 
> stops any possibility of unification with 'like' types.  Same with Make_U.
> 
> Note that VB1 will still be of type VB, and you can be sure of that 
> because the constraint in Make_U's signature will enforce it -- only a 
> bit later than at declaration time, at use-time.
> 

Understood. I was only thinking of the interface.

>> My question is: is their any way I may organize the modules or
>> indicate shared types in order to use a (very extensive) VB
>> interface (Or VB1 module)? Specifically how do I enforce the
>> shared type:
>>
>>  U1.instance VB1.t = U1.t = Make_U(VB1).t
> First, try the above.  It may help.  If it does not, then you will need 
> to add explicit sharing constraints.  But which sharing constraints are 
> *really* needed will be the ones revealed by first removing the type 
> annotations you currently have.
> 

Worked correctly. However I need only remove the U in Make_U : U and
change it to a simple Make_U. "U1.t" now becomes visible and binds
correctly.

> Note that you should not have to re-organize your modules at all to 
> achieve this [at least, not in this example].
> 

Worked like a charm. No additional changes.

Thank you,
Hugo F.


> Jacques
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Shared types: circular dependency in modules with polymorphic type
  2009-05-13 19:40 ` [Caml-list] " Jacques Carette
  2009-05-14  7:58   ` Hugo Ferreira
@ 2009-05-14 11:41   ` Hugo Ferreira
  2009-05-14 12:11     ` [Caml-list] " Peng Zang
  1 sibling, 1 reply; 10+ messages in thread
From: Hugo Ferreira @ 2009-05-14 11:41 UTC (permalink / raw)
  To: caml-list

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 )


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] Shared types: circular dependency in modules with polymorphic type
  2009-05-14 11:41   ` Shared types: circular " Hugo Ferreira
@ 2009-05-14 12:11     ` Peng Zang
  2009-05-14 12:46       ` Hugo Ferreira
  0 siblings, 1 reply; 10+ messages in thread
From: Peng Zang @ 2009-05-14 12:11 UTC (permalink / raw)
  To: caml-list; +Cc: Hugo Ferreira

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I think this is because UI.t is abstract and is in fact, never created.  You 
need to tell the old caml that UI.t is actuall an int VI.t.  Then it should 
work.

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

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

Works like a charm for me,

Peng


On Thursday 14 May 2009 07:41:24 am Hugo Ferreira wrote:
> 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 )
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.7 (GNU/Linux)

iD8DBQFKDAqMfIRcEFL/JewRAikyAKDWuRFALodBLy5NqWJFBH4MDD5FdgCg0Q5J
U4I+34lrt7QjpkzQwZpztEE=
=VbUW
-----END PGP SIGNATURE-----


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] Shared types: circular dependency in modules with polymorphic type
  2009-05-14 12:11     ` [Caml-list] " Peng Zang
@ 2009-05-14 12:46       ` Hugo Ferreira
  2009-05-14 13:20         ` Peng Zang
  0 siblings, 1 reply; 10+ messages in thread
From: Hugo Ferreira @ 2009-05-14 12:46 UTC (permalink / raw)
  To: peng.zang; +Cc: caml-list

Hello,

Appreciate the feedback.

Peng Zang wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> I think this is because UI.t is abstract and is in fact, never created.  You 
> need to tell the old caml that UI.t is actuall an int VI.t.  Then it should 
> work.
> 

True. However in the real case I am not dealing with an "int"
but some more complicated data defined in U. I wanted to avoid
"looking" into U to know what U.t is and therefore set VI.t
accordingly.

This is important because I will use different U implementations.
For each such cases I would have to create a module for each U
implementation. Not doable.


> module Make_P (VI : VB)
>               (UI : U with type t = int VI.t)
>               (RI : R with type t = UI.t and type instance = UI.instance ) =
> struct ... end
> 
> module P1 = Make_P ( VB1 ) ( U1 ) ( R1 )
> 
> Works like a charm for me,
> 

I guess I will have to rethink my modules/types 8-(.

Thanks,
Hugo F.

> Peng
> 
> 
> On Thursday 14 May 2009 07:41:24 am Hugo Ferreira wrote:
>> 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 )
>>
>> _______________________________________________
>> Caml-list mailing list. Subscription management:
>> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
>> Archives: http://caml.inria.fr
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v2.0.7 (GNU/Linux)
> 
> iD8DBQFKDAqMfIRcEFL/JewRAikyAKDWuRFALodBLy5NqWJFBH4MDD5FdgCg0Q5J
> U4I+34lrt7QjpkzQwZpztEE=
> =VbUW
> -----END PGP SIGNATURE-----
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] Shared types: circular dependency in modules with polymorphic type
  2009-05-14 12:46       ` Hugo Ferreira
@ 2009-05-14 13:20         ` Peng Zang
  2009-05-14 13:28           ` Hugo Ferreira
  0 siblings, 1 reply; 10+ messages in thread
From: Peng Zang @ 2009-05-14 13:20 UTC (permalink / raw)
  To: caml-list; +Cc: Hugo Ferreira

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

You could try factoring the complicated type out of U.t and keep it abstract.  
All that was holding back your original solution from working was the fact 
that the type was defined in U and so couldn't be shared.

Maybe something like:

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

Peng
              


On Thursday 14 May 2009 08:46:58 am Hugo Ferreira wrote:
> Hello,
>
> Appreciate the feedback.
>
> Peng Zang wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> >
> > I think this is because UI.t is abstract and is in fact, never created. 
> > You need to tell the old caml that UI.t is actuall an int VI.t.  Then it
> > should work.
>
> True. However in the real case I am not dealing with an "int"
> but some more complicated data defined in U. I wanted to avoid
> "looking" into U to know what U.t is and therefore set VI.t
> accordingly.
>
> This is important because I will use different U implementations.
> For each such cases I would have to create a module for each U
> implementation. Not doable.
>
> > module Make_P (VI : VB)
> >               (UI : U with type t = int VI.t)
> >               (RI : R with type t = UI.t and type instance = UI.instance
> > ) = struct ... end
> >
> > module P1 = Make_P ( VB1 ) ( U1 ) ( R1 )
> >
> > Works like a charm for me,
>
> I guess I will have to rethink my modules/types 8-(.
>
> Thanks,
> Hugo F.
>
> > Peng
> >
> > On Thursday 14 May 2009 07:41:24 am Hugo Ferreira wrote:
> >> 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 )
> >>
> >> _______________________________________________
> >> Caml-list mailing list. Subscription management:
> >> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> >> Archives: http://caml.inria.fr
> >> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> >> Bug reports: http://caml.inria.fr/bin/caml-bugs
> >
> > -----BEGIN PGP SIGNATURE-----
> > Version: GnuPG v2.0.7 (GNU/Linux)
> >
> > iD8DBQFKDAqMfIRcEFL/JewRAikyAKDWuRFALodBLy5NqWJFBH4MDD5FdgCg0Q5J
> > U4I+34lrt7QjpkzQwZpztEE=
> > =VbUW
> > -----END PGP SIGNATURE-----
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.7 (GNU/Linux)

iD8DBQFKDBqUfIRcEFL/JewRAoVtAKCiNVC/v1+qBaKPUZxZrMzHsOKfpACfQdoI
CJ4kV/JL6HCcrwVAYYluY9s=
=HTzi
-----END PGP SIGNATURE-----


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] Shared types: circular dependency in modules with polymorphic type
  2009-05-14 13:20         ` Peng Zang
@ 2009-05-14 13:28           ` Hugo Ferreira
  0 siblings, 0 replies; 10+ messages in thread
From: Hugo Ferreira @ 2009-05-14 13:28 UTC (permalink / raw)
  To: peng.zang; +Cc: caml-list

Hi,

Peng Zang wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> You could try factoring the complicated type out of U.t and keep it abstract.  
> All that was holding back your original solution from working was the fact 
> that the type was defined in U and so couldn't be shared.
> 
> Maybe something like:
> 
> module Make_P (VI:VB)
>               (T:COMPLEXTYPE)
> 	      (UI:U with type instance = T.t and type t = T.t VI.t)
>               (RI:R with type instance = UI.instance and type t = UI.t)
> struct .. end


Yes, that is what am I going to do.
Something similar was also suggested by someone else.

Thank you,
Hugo F.


> 
> Peng
>               
> 
> 
> On Thursday 14 May 2009 08:46:58 am Hugo Ferreira wrote:
>> Hello,
>>
>> Appreciate the feedback.
>>
>> Peng Zang wrote:
>>> -----BEGIN PGP SIGNED MESSAGE-----
>>> Hash: SHA1
>>>
>>> I think this is because UI.t is abstract and is in fact, never created. 
>>> You need to tell the old caml that UI.t is actuall an int VI.t.  Then it
>>> should work.
>> True. However in the real case I am not dealing with an "int"
>> but some more complicated data defined in U. I wanted to avoid
>> "looking" into U to know what U.t is and therefore set VI.t
>> accordingly.
>>
>> This is important because I will use different U implementations.
>> For each such cases I would have to create a module for each U
>> implementation. Not doable.
>>
>>> module Make_P (VI : VB)
>>>               (UI : U with type t = int VI.t)
>>>               (RI : R with type t = UI.t and type instance = UI.instance
>>> ) = struct ... end
>>>
>>> module P1 = Make_P ( VB1 ) ( U1 ) ( R1 )
>>>
>>> Works like a charm for me,
>> I guess I will have to rethink my modules/types 8-(.
>>
>> Thanks,
>> Hugo F.
>>
>>> Peng
>>>
>>> On Thursday 14 May 2009 07:41:24 am Hugo Ferreira wrote:
>>>> 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 )
>>>>
>>>> _______________________________________________
>>>> Caml-list mailing list. Subscription management:
>>>> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
>>>> Archives: http://caml.inria.fr
>>>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>>>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>>> -----BEGIN PGP SIGNATURE-----
>>> Version: GnuPG v2.0.7 (GNU/Linux)
>>>
>>> iD8DBQFKDAqMfIRcEFL/JewRAikyAKDWuRFALodBLy5NqWJFBH4MDD5FdgCg0Q5J
>>> U4I+34lrt7QjpkzQwZpztEE=
>>> =VbUW
>>> -----END PGP SIGNATURE-----
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v2.0.7 (GNU/Linux)
> 
> iD8DBQFKDBqUfIRcEFL/JewRAoVtAKCiNVC/v1+qBaKPUZxZrMzHsOKfpACfQdoI
> CJ4kV/JL6HCcrwVAYYluY9s=
> =HTzi
> -----END PGP SIGNATURE-----
> 
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] Shared types: dependency in modules with polymorphic type
  2009-05-14  7:58   ` Hugo Ferreira
@ 2009-05-14 14:42     ` Andreas Rossberg
  2009-05-14 15:06       ` Hugo Ferreira
  0 siblings, 1 reply; 10+ messages in thread
From: Andreas Rossberg @ 2009-05-14 14:42 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 889 bytes --]

On May 14, 2009, at 09.58 h, Hugo Ferreira wrote:
>
>>> My question is: is their any way I may organize the modules or
>>> indicate shared types in order to use a (very extensive) VB
>>> interface (Or VB1 module)? Specifically how do I enforce the
>>> shared type:
>>>
>>> U1.instance VB1.t = U1.t = Make_U(VB1).t
>> First, try the above.  It may help.  If it does not, then you will  
>> need to add explicit sharing constraints.  But which sharing  
>> constraints are *really* needed will be the ones revealed by first  
>> removing the type annotations you currently have.
>
> Worked correctly. However I need only remove the U in Make_U : U and
> change it to a simple Make_U. "U1.t" now becomes visible and binds
> correctly.

FWIW, the "proper" solution is not to drop the annotation, but to  
refine it to "U with type t = int Vb.t" in the definition of the  
functor.

- Andreas


[-- Attachment #2: Type: text/html, Size: 1666 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Caml-list] Shared types: dependency in modules with polymorphic type
  2009-05-14 14:42     ` Andreas Rossberg
@ 2009-05-14 15:06       ` Hugo Ferreira
  0 siblings, 0 replies; 10+ messages in thread
From: Hugo Ferreira @ 2009-05-14 15:06 UTC (permalink / raw)
  To: Andreas Rossberg; +Cc: caml-list

Andreas Rossberg wrote:
> On May 14, 2009, at 09.58 h, Hugo Ferreira wrote:
>>
>>>> My question is: is their any way I may organize the modules or
>>>> indicate shared types in order to use a (very extensive) VB
>>>> interface (Or VB1 module)? Specifically how do I enforce the
>>>> shared type:
>>>>
>>>> U1.instance VB1.t = U1.t = Make_U(VB1).t
>>> First, try the above.  It may help.  If it does not, then you will 
>>> need to add explicit sharing constraints.  But which sharing 
>>> constraints are *really* needed will be the ones revealed by first 
>>> removing the type annotations you currently have.
>>
>> Worked correctly. However I need only remove the U in Make_U : U and
>> change it to a simple Make_U. "U1.t" now becomes visible and binds
>> correctly.
> 
> FWIW, the "proper" solution is not to drop the annotation, but to refine 
> it to "U with type t = int Vb.t" in the definition of the functor.
> 

I agree. I finally had to go that route.
However that means I have to change my modules.
This is taking some time to do. I was
hoping to avoid such reworking.

Thanks,
Hugo F.


> - Andreas
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-05-14 15:06 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-13 19:12 Shared types: dependency in modules with polymorphic type Hugo Ferreira
2009-05-13 19:40 ` [Caml-list] " Jacques Carette
2009-05-14  7:58   ` Hugo Ferreira
2009-05-14 14:42     ` Andreas Rossberg
2009-05-14 15:06       ` Hugo Ferreira
2009-05-14 11:41   ` Shared types: circular " Hugo Ferreira
2009-05-14 12:11     ` [Caml-list] " Peng Zang
2009-05-14 12:46       ` Hugo Ferreira
2009-05-14 13:20         ` Peng Zang
2009-05-14 13:28           ` Hugo Ferreira

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).