From: SEROT Jocelyn <Jocelyn.SEROT@univ-bpclermont.fr>
To: Josh Berdine <josh@berdine.net>
Cc: Leo White <lpw25@cam.ac.uk>, caml-list <caml-list@inria.fr>
Subject: Re: [Caml-list] Question on functors (again...)
Date: Tue, 21 Jan 2014 15:30:07 +0100 [thread overview]
Message-ID: <20140121153007.Horde.911-b1nON_CEk0EaoT-0QA2@wmail.univ-bpclermont.fr> (raw)
In-Reply-To: <87txcxlggc.fsf@berdine.net>
Josh Berdine <josh@berdine.net> a écrit :
>
> Shouldn't Elt.t and elt in SET be equal? The following typechecks,
> though maybe not what you want:
>
>> [...]
>
> Cheers, Josh
Thanks a lot Josh !
The magic line to add was :
type elt = Elt.t
in the SET signature..
This is so obvious afterwards that i should have thought about it
right from the start (as often...) ;-)
For those interested, here are the signature and implementation of a
set module extending that provided in the std lib with a cartesian
product operation (in fact two product ops) and a "string_of" op.
Thx again.
Best wishes
Jocelyn
(* mset.mli *)
module type ELT =
sig
include Set.OrderedType
val string_of: t -> string
end
module type SET = sig
module Elt : ELT
include Set.S with type elt = Elt.t
val of_list: elt list -> t
val string_of: t -> string
end
(* The [Make] functor builds an implementation of a Set given an
implementation of its elements *)
module Make (E : ELT) : SET with module Elt = E and type elt = E.t
(* The [MakeProduct] functor builds an implementation the cartesian
product of two sets *)
module MakeProduct (S1: SET) (S2: SET) :
sig
include SET with type Elt.t = S1.elt * S2.elt
val product : S1.t -> S2.t -> t
end
(* This is the signature of the last argument to the [MakeProduct'] functor.
It describes how to build the product of two set elements *)
module type MakePair =
functor (E1: ELT)
-> functor (E2: ELT)
-> sig
include ELT with type t = E1.t * E2.t
val product : E1.t -> E2.t -> t
end
(* The [MakeProduct'] higher-order functor builds a customized
implementation of the cartesian products of two sets
when the product of the respective set elements is explicitely
specified with a dedicated [MakePair] functor *)
(* Note: the [MakeProduct] functor is just a specialization of
[MakeProduct'] *)
module MakeProduct'
(S1: SET)
(S2: SET)
(F: MakePair) :
sig
include SET with type Elt.t = S1.elt * S2.elt
val product : S1.t -> S2.t -> t
end
(* mset.ml *)
module type ELT =
sig
include Set.OrderedType
val string_of: t -> string
end
module type SET = sig
module Elt : ELT
include Set.S with type elt = Elt.t
val of_list: elt list -> t
val string_of: t -> string
end
let string_of_list sep f s =
let rec h = function
[] -> ""
| [x] -> f x
| x::xs -> f x ^ sep ^ h xs in
h s
module Make (E : ELT) : SET with module Elt = E and type elt = E.t = struct
module Elt = E
module S = Set.Make(E)
include S
let string_of s = "{" ^ string_of_list "," E.string_of (S.elements s) ^ "}"
let of_list l = List.fold_left (fun s e -> S.add e s) S.empty l
end
module type MakePair =
functor (E1: ELT)
-> functor (E2: ELT)
-> sig
include ELT with type t = E1.t * E2.t
val product : E1.t -> E2.t -> t
end
module MakeProduct'
(S1: SET)
(S2: SET)
(F: MakePair) :
sig
include SET with type Elt.t = S1.elt * S2.elt
val product : S1.t -> S2.t -> t
end = struct
module P = F(S1.Elt)(S2.Elt)
module S = Make(P)
include S
let product s1 s2 =
let f x y t = S.add (P.product x y) t in
let g x t = S2.fold (f x) s2 t in
S1.fold g s1 S.empty
end
module MakeProduct (S1: SET) (S2: SET) =
MakeProduct'
(S1)
(S2)
(functor (E1: ELT) -> functor (E2: ELT) -> struct
type t = E1.t * E2.t
let compare = Pervasives.compare
let product x y = x,y
let string_of (x,y) = "(" ^ E1.string_of x ^ "," ^ E2.string_of y ^ ")"
end)
next prev parent reply other threads:[~2014-01-21 14:30 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-20 16:34 Jocelyn Sérot
2014-01-20 20:57 ` Leo White
2014-01-21 11:09 ` SEROT Jocelyn
2014-01-21 11:30 ` Josh Berdine
2014-01-21 14:30 ` SEROT Jocelyn [this message]
2014-01-21 13:32 ` Leo White
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=20140121153007.Horde.911-b1nON_CEk0EaoT-0QA2@wmail.univ-bpclermont.fr \
--to=jocelyn.serot@univ-bpclermont.fr \
--cc=caml-list@inria.fr \
--cc=josh@berdine.net \
--cc=lpw25@cam.ac.uk \
/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;
as well as URLs for NNTP newsgroup(s).