Version française
Home     About     Download     Resources     Contact us    
Browse thread
Functors + polymorphism = confusion
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jonathan Bryant <jtbryant@v...>
Subject: Re: [Caml-list] Functors + polymorphism = confusion

On Jun 21, 2007, at 10:08 AM, Chris King wrote:

> The important thing to remember with Caml modules is that it will hide
> type relations unless you tell it otherwise:
>
> Here modules A and B are of type Message, which define an abstract
> type t.  Caml doesn't automatically fill in this type definition for
> you, so the module returned by BindFunction will only be able to
> operate over a pair of abstract types.  Not good!

Ah, I see the error now!

>
> The solution to this (which you will see used in functorized library
> modules such as Map and Set) is to add the derivation of types A.t and
> B.t to your output signature using the "with" syntax:
>
> module BindFunction :
> functor (F : PolyFunction) ->
> functor (A : Message) ->
> functor (B : Message) ->
> Function with type A.t = A.t and type B.t = B.t
>

Works perfectly!  I had always been a little confused as to exactly  
what the "with" syntax was accomplishing, and even with your  
explanation it took a while for me to see how to use it.  Thanks for  
the clarification.

>
>> module BindMessage =
>>   functor (P : PolyMessage) ->
>>   functor (M : Message) ->
>>   struct
>>     module P = P (M)
>>     type t = M.t P.t
>>     let to_string m = P.to_string m
>>     let of_string s = P.of_string s
>>   end
>
> Because you are not restricting the output signatures in your
> implementation, Caml preserves the type relationships (it only
> discards them at the interface level).  However if you did specify the
> output signature here (as the library modules do) you would need to
> use the same construct.
>

I have gone back and used the same "with" syntax on my prebuilt  
messages and it solved another type issue I was having :)

I do specify the output signature (in the .mli file):

module BindMessage :
   functor (P : PolyMessage) ->
   functor (M : Message) ->
   Message

but now it's:

module BindMessage :
   functor (P : PolyMessage) ->
   functor (M : Message) ->
   Message with type t = M.t P(M).t

>
> Hope this helps... I can attest that this stuff is pretty confusing  
> at first. :)

Yes.  I am learning more about the module system than I think I ever  
wanted to know.  My project makes heavy use of (read: abuses) the  
modules system :)

--Jonathan

>
> - Chris
>
> _______________________________________________
> 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