Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: "Jérémie Lumbroso" <jeremie.lumbroso@etu.upmc.fr>
To: "Keiko Nakata" <keiko@kurims.kyoto-u.ac.jp>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Separating two mutually recursive modules
Date: Thu, 21 Aug 2008 13:00:36 +0200	[thread overview]
Message-ID: <2b7b425b0808210400j618e461fre54f73612b920e4a@mail.gmail.com> (raw)
In-Reply-To: <20080821.182901.68534700.keiko@kurims.kyoto-u.ac.jp>

Hello,

> Can I look at the code which does not type check without Obj.magic?
> Ideally something like if I comment out Obj.magic then I get a type
> error, and if I comment it in then the code type checks, so that I can
> identify the point of the issue? (In the context of this simplified
> example of Boxes & Validator)

Yes, and thank you for taking an interest! I do have a warning though:
this code is not correct, in the sense that, it doesn't type and it
*shouldn't* type (because while in this case Validator.Boxes.t *is*
equivalent to B.t, there is nothing but my "good will" that guarantees in
the specs of the modules that this is so).

Attempts to make this correct (for the type checker) with "with type"
conditions have failed.

The mutually recursive version I posted in the previous message is an
"evolution" from this (and that mutually recursive version, contrarily to
this one is "correct").

  <code:"code_min_with_objmagic.ml">
  module type BOXES_PROVIDER =
  sig
    type t
  end

  module type VALIDATOR =
  sig
    module Boxes : BOXES_PROVIDER

    type t = Me of int | Node of t * t | B of Boxes.t

    val fold_on_B : (Boxes.t -> 'a) -> ('a -> 'a -> 'a) -> 'a -> t -> 'a
  end


  module BoxesProvider(Validator : VALIDATOR) : BOXES_PROVIDER =
  struct

    module rec A : sig
      type t = | Anil
  	     | Aout of Validator.t

      val o_f : ('a -> bool) -> ('a -> bool) -> t -> bool
    end =
    struct
      type t = | Anil
  	     | Aout of Validator.t

      (* There is no equality between Validator.Boxes.t and B.t, i.e.:
         failing to see this is not a problem with the typechecker.
         To get the type error, replace with "let crosstype x = x". *)

      let crosstype (x : Validator.Boxes.t) =
        ((Obj.magic x) : B.t)

      let o_f p1 p2 =
        let rec aux = function
  	| Anil    -> false
  	| Aout tv ->
  	    Validator.fold_on_B (fun x -> B.o_f p1 p2 (crosstype x)) (||) false tv
        in
        aux
    end

    and B : sig
      type t = | Bnil
  	     | Bout of A.t * t
  		
      val o_f : ('a -> bool) -> ('a -> bool) -> t -> bool

    end =
    struct
      type t = | Bnil
  	     | Bout of A.t * t
  		
      let o_f p1 p2 =
        let rec aux = function
  	| Bnil        -> false
  	| Bout(a, tv) -> (A.o_f p1 p2 a) || (aux tv)
        in
        aux
    end

    type t = B.t

  end


  module rec Validator : VALIDATOR (* with type Boxes.t =
Validator.Boxes.t ?? *) =
  struct

    module Boxes = BoxesProvider(Validator)

    type t = Me of int | Node of t * t | B of Boxes.t

    let fold_on_B f combinator default =
      let rec aux = function
        | Node(b1, b2) -> combinator (aux b1) (aux b2)
        | B r	     -> f r
        | _  	     -> default
      in
      aux
  end
  </code>

> >   (********************)
> >   (* MODULE Validator *)
> >   (********************)
> >
> >   and Validator : sig
> >
> >     (* This type has been simplified for explanatory purposes. *)
> >     (* IDEALLY, Boxes.B.t would simply be B.t. *)
> >     type t = Me of int | Node of t * t | B of Boxes.B.t
> >
> >     val fold_on_B : (Boxes.B.t -> 'a) -> ('a -> 'a -> 'a) -> 'a -> t -> 'a
> >
> >   end =
>
> But B is not in the scope, isn't it?

Indeed. What I meant to say is, "IDEALLY, Boxes.B.t would simply be
Boxes.t" (and Validator would not need to know about submodules A and/or
B).

Please, of course, don't hesitate to ask for any other details you might
need (and don't hesitate to tell me if this Obj.magic code is not what you
needed!).

All the best,
Jérémie


  reply	other threads:[~2008-08-21 11:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-20 23:54 Separating two mutually recursive modules (was Specifying recursive modules?) Jérémie Lumbroso
2008-08-21  9:29 ` [Caml-list] Separating two mutually recursive modules Keiko Nakata
2008-08-21 11:00   ` Jérémie Lumbroso [this message]
2008-08-22  8:56     ` Keiko Nakata
2008-08-23 16:40       ` Jérémie Lumbroso
2008-08-27 13:09         ` Keiko Nakata

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=2b7b425b0808210400j618e461fre54f73612b920e4a@mail.gmail.com \
    --to=jeremie.lumbroso@etu.upmc.fr \
    --cc=caml-list@inria.fr \
    --cc=keiko@kurims.kyoto-u.ac.jp \
    /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