From: John Prevost <j.prevost@gmail.com>
To: Ocaml Mailing List <caml-list@inria.fr>
Subject: Re: [Caml-list] Functors and classes
Date: Tue, 3 Aug 2004 19:24:51 -0400 [thread overview]
Message-ID: <d849ad2a040803162470ad4f16@mail.gmail.com> (raw)
In-Reply-To: <Pine.LNX.4.58.0408031500000.22016@shell2.speakeasy.net>
GOT IT!
The trick is to provide a cast operation from the original module,
which can then be used by the functor. The functor gets grumpy
because it doesn't have enough information (or perhaps smarts) to be
sure the type can be unified. But the original creator surely does.
Find below the complete source--I separated things up in some
semblance of the modules you'd expect to find in wild .ml and .mli
files, just to be sure that doesn't break anything. :)
The best part is that even though the functor has to go through "toss"
to get to the known methods of a connection, the module that uses the
functor knows the full identity of the type, and can access all
methods (and use other functions that work on the type) of the
original object--preserving extensibility.
module Things = (* Things.ml *)
(struct
class type base_connection =
object
method a : int
end
module type Thing_T =
sig
type connection
val connect : unit -> connection
val toss : connection -> base_connection
end
module type Thing_Pool_T =
sig
type connection
val connect : unit -> connection
val test : connection -> int
end
module Thing_Pool (Thing : Thing_T) :
Thing_Pool_T with type connection = Thing.connection =
struct
type connection = Thing.connection
let connect () = Thing.connect ()
let test c = (Thing.toss c)#a + 1
end
end : sig (* Things.mli *)
class type base_connection =
object
method a : int
end
module type Thing_T =
sig
type connection
val connect : unit -> connection
val toss : connection -> base_connection
end
module type Thing_Pool_T =
sig
type connection
val connect : unit -> connection
val test : connection -> int
end
module Thing_Pool : functor (Thing : Thing_T) ->
Thing_Pool_T with type connection = Thing.connection
end)
(* database package to be pooled *)
module Thing_Test = (* Thing_Test.ml *)
(struct
class connection =
object
method a = 1
method b = 2
end
let connect () = new connection
let toss c = (c :> Things.base_connection)
end : sig (* Thing_Test.mli *)
class connection :
object
method a : int
method b : int
end
val connect : unit -> connection
val toss : connection -> Things.base_connection
end)
(* package using the pool *)
module Program = (* Program.ml *)
struct
open Things
module X = Thing_Pool(Thing_Test)
let x = X.connect ()
let a = x#a
let b = x#b
end
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
next prev parent reply other threads:[~2004-08-03 23:24 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-08-03 12:02 Richard Jones
2004-08-03 12:10 ` Richard Jones
2004-08-03 13:17 ` Richard Jones
2004-08-03 15:06 ` John Prevost
2004-08-03 15:12 ` Richard Jones
2004-08-03 15:27 ` John Prevost
2004-08-03 15:28 ` John Prevost
2004-08-03 19:57 ` brogoff
2004-08-03 22:05 ` brogoff
2004-08-03 23:24 ` John Prevost [this message]
2004-08-03 15:50 ` Richard Jones
2004-08-03 16:23 ` John Prevost
2004-08-03 16:42 ` Richard Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d849ad2a040803162470ad4f16@mail.gmail.com \
--to=j.prevost@gmail.com \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox