caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] fighting the type system
@ 2011-03-23 22:01 Joel Reymont
  2011-03-23 22:19 ` [Caml-list] " Joel Reymont
  2011-03-23 23:56 ` [Caml-list] " Jacques Garrigue
  0 siblings, 2 replies; 6+ messages in thread
From: Joel Reymont @ 2011-03-23 22:01 UTC (permalink / raw)
  To: caml-list

How do I do this?

	Thanks in advance, Joel

---

How do I do this?

module T = Foo

module Ads = 
struct
  let read_request = T.read_request
  let read_response = T.read_response
  let request () = 
    let req = new T.request in
    ...
    req
...

--- Foo.mli

open Thrift
class request :
object ('a)
  method copy : 'a
  method write : Protocol.t -> unit
end
val read_request : Protocol.t -> request
class response :
object ('a)
  method copy : 'a
  method write : Protocol.t -> unit
end
val read_response : Protocol.t -> response

--- Util.ml

type 'a writable = < write : Protocol.t -> unit; .. > as 'a

module type Endpoint = 
sig 
  val request : unit -> 'a writable
  val response : 'a writable -> 'b writable
  val read_request : Protocol.t -> 'a writable
  val read_response : Protocol.t -> 'a writable
end


--------------------------------------------------------------------------
- for hire: mac osx device driver ninja, kernel extensions and usb drivers
---------------------+------------+---------------------------------------
http://wagerlabs.com | @wagerlabs | http://www.linkedin.com/in/joelreymont
---------------------+------------+---------------------------------------




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

* [Caml-list] Re: fighting the type system
  2011-03-23 22:01 [Caml-list] fighting the type system Joel Reymont
@ 2011-03-23 22:19 ` Joel Reymont
  2011-03-23 23:52   ` Joel Reymont
  2011-03-23 23:56 ` [Caml-list] " Jacques Garrigue
  1 sibling, 1 reply; 6+ messages in thread
From: Joel Reymont @ 2011-03-23 22:19 UTC (permalink / raw)
  To: caml-list

One of the issues is that the full definition of Foo.mli is larger than I posted (below) and I'm using other methods apart from write, e.g. grab_page.

My writable type really needs to include write -and- grab_page, for example.

	Thanks, Joel

---

open Thrift
class request :
object ('a)
  method get_page : Doc_types.document option
  method grab_page : Doc_types.document
  method set_page : Doc_types.document -> unit
  method unset_page : unit
  method reset_page : unit
  method copy : 'a
  method write : Protocol.t -> unit
end
val read_request : Protocol.t -> request
class response :
object ('a)
  method get_page : Doc_types.document option
  method grab_page : Doc_types.document
  method set_page : Doc_types.document -> unit
  method unset_page : unit
  method reset_page : unit
  method get_sidebar_pages : Doc_types.document list option
  method grab_sidebar_pages : Doc_types.document list
  method set_sidebar_pages : Doc_types.document list -> unit
  method unset_sidebar_pages : unit
  method reset_sidebar_pages : unit
  method copy : 'a
  method write : Protocol.t -> unit
end
val read_response : Protocol.t -> response

--------------------------------------------------------------------------
- for hire: mac osx device driver ninja, kernel extensions and usb drivers
---------------------+------------+---------------------------------------
http://wagerlabs.com | @wagerlabs | http://www.linkedin.com/in/joelreymont
---------------------+------------+---------------------------------------





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

* [Caml-list] Re: fighting the type system
  2011-03-23 22:19 ` [Caml-list] " Joel Reymont
@ 2011-03-23 23:52   ` Joel Reymont
  0 siblings, 0 replies; 6+ messages in thread
From: Joel Reymont @ 2011-03-23 23:52 UTC (permalink / raw)
  To: caml-list

A much reduced version. Help!

--- Util.ml

open ZMQ
open ZMQ.Socket
open Thrift

let make_proto = 
  let inbuf = Buffer.create 0
  and outbuf = Buffer.create 0 in
  let tx = new TBufferTransport.t inbuf outbuf in
  new TBinaryProtocol.t tx

type 'a request = < write : Protocol.t -> unit; .. > as 'a

module type Endpoint = 
sig 
  val request : unit -> 'a request
  val read_request : Protocol.t -> 'a request
end

module SimpleService (E: Endpoint) = 
struct 
  let server endpoint =  
    let proto = make_proto in
    E.read_request proto
end

--- A.ml

module U = Util
module T = AdCampaign_types

module Ads = 
struct
  let read_request = T.read_request
  let request () = new T.request
end

module M = U.SimpleService(Ads)

--- Error

File "src/ads.ml", line 10, characters 27-30:
Error: Signature mismatch:
       Modules do not match:
         sig
           val read_request : Thrift.Protocol.t -> T.request
           val request : unit -> T.request
         end
       is not included in
         U.Endpoint
       Values do not match:
         val request : unit -> T.request
       is not included in
         val request :
           unit -> < write : Thrift.Protocol.t -> unit; .. > U.request


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

* Re: [Caml-list] fighting the type system
  2011-03-23 22:01 [Caml-list] fighting the type system Joel Reymont
  2011-03-23 22:19 ` [Caml-list] " Joel Reymont
@ 2011-03-23 23:56 ` Jacques Garrigue
  2011-03-24  0:16   ` Joel Reymont
  1 sibling, 1 reply; 6+ messages in thread
From: Jacques Garrigue @ 2011-03-23 23:56 UTC (permalink / raw)
  To: Joel Reymont; +Cc: caml-list

On 2011/03/24, at 7:01, Joel Reymont wrote:

> How do I do this?
> 
> 	Thanks in advance, Joel

Well, you don't because this is clearly unsound.

> --- Util.ml
> 
> type 'a writable = < write : Protocol.t -> unit; .. > as 'a
> 
> module type Endpoint = 
> sig 
>  val request : unit -> 'a writable
>  val response : 'a writable -> 'b writable
>  val read_request : Protocol.t -> 'a writable
>  val read_response : Protocol.t -> 'a writable
> end

Your definition of 'a writable is actually equivalent to writing

  class type writable = object method write : Protocol.t -> unit end

and replacing uses of 'a writable by #writable.
The trouble is that returning a value of type #writable is unsound,
since it means that this value has any possible method, including write.
So you would be able to write:
     (request ())#foo
and have the type checker happily comply.

I'm not sure of what you're trying to do.
If you just want the Endpoint interface to specify an object type
containing at least write, you could use a private row type:

module type Endpoint = 
sig
 type writable = private <write : Protocol.t -> unit; .. >
 val request : unit -> writable
 val response : writable -> writable
 val read_request : Protocol.t -> writable
 val read_response : Protocol.t -> writable
end

You can then instantiate it with a concrete type, using
   Endpoint with type writable := mywriter

Jacques Garrigue


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

* Re: [Caml-list] fighting the type system
  2011-03-23 23:56 ` [Caml-list] " Jacques Garrigue
@ 2011-03-24  0:16   ` Joel Reymont
  2011-03-24  0:48     ` Jacques Garrigue
  0 siblings, 1 reply; 6+ messages in thread
From: Joel Reymont @ 2011-03-24  0:16 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: caml-list

Jacques,

On Mar 23, 2011, at 11:56 PM, Jacques Garrigue wrote:

> If you just want the Endpoint interface to specify an object type
> containing at least write, you could use a private row type:

The private row type is what I was clearly missing.

Why does it work with the private row type, though? 

Are there other uses for 'private' in a module?

Is the use of private row types described somewhere?

	Thanks, Joel

--------------------------------------------------------------------------
- for hire: mac osx device driver ninja, kernel extensions and usb drivers
---------------------+------------+---------------------------------------
http://wagerlabs.com | @wagerlabs | http://www.linkedin.com/in/joelreymont
---------------------+------------+---------------------------------------




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

* Re: [Caml-list] fighting the type system
  2011-03-24  0:16   ` Joel Reymont
@ 2011-03-24  0:48     ` Jacques Garrigue
  0 siblings, 0 replies; 6+ messages in thread
From: Jacques Garrigue @ 2011-03-24  0:48 UTC (permalink / raw)
  To: Joel Reymont; +Cc: caml-list

On 2011/03/24, at 9:16, Joel Reymont wrote:
>> If you just want the Endpoint interface to specify an object type
>> containing at least write, you could use a private row type:
> 
> The private row type is what I was clearly missing.
> 
> Why does it work with the private row type, though? 

Because if you just define a constrained type every occurrence is
going to be a different instance of this type, while a private row type
ensures that this is the same type throughout the module.

> Are there other uses for 'private' in a module?
> 
> Is the use of private row types described somewhere?

They are described described in section 7.9.3 of the manual:
http://caml.inria.fr/pub/docs/manual-ocaml/manual021.html#toc76

You can find more examples in my paper:
http://www.math.nagoya-u.ac.jp/~garrigue/papers/privaterows-aplas2006.pdf

Cheers,

Jacques Garrigue

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

end of thread, other threads:[~2011-03-24  0:48 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-23 22:01 [Caml-list] fighting the type system Joel Reymont
2011-03-23 22:19 ` [Caml-list] " Joel Reymont
2011-03-23 23:52   ` Joel Reymont
2011-03-23 23:56 ` [Caml-list] " Jacques Garrigue
2011-03-24  0:16   ` Joel Reymont
2011-03-24  0:48     ` Jacques Garrigue

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).