caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
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)






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