Loading ...
Sorry, an error occurred while loading the content.
 

Re: "ocaml_beginners"::[] Splitting recursive data types into recusrive modules

Expand Messages
  • Hugo Ferreira
    Hi Martin, ... This is the issue really. I have a mutually recursive data structures and want to split them. ... Got this far but I need to define a data
    Message 1 of 10 , Mar 1, 2006
      Hi Martin,

      Martin Jambon wrote:
      > On Mon, 27 Feb 2006, Hugo Ferreira wrote:
      >
      >>The idea of using recursive modules was to split up the implementations
      ...
      > If you don't need to define mutually recursive non-functions, everything
      > should be fine.

      This is the issue really. I have a mutually recursive data structures
      and want to split them.

      >
      > That works:
      >
      > module rec A : sig val f : unit -> unit end =
      > struct
      > let f () = B.f ()
      > end
      > and B : sig val f : unit -> unit end =
      > struct
      > let f () = A.f ()
      > end
      >

      Got this far but I need to define a data structure for the
      implementation. (Above not really useful because we just have functions
      that loop at runtime.)

      > And that doesn't work ("Cannot safely evaluate the definition of the
      > recursively-defined module A"):
      >
      > module rec A : sig val f : unit -> unit val null : int end =
      > struct
      > let f () = B.f ()
      > let null = 0
      > end
      > and B : sig val f : unit -> unit val null : int end =
      > struct
      > let f () = A.f ()
      > let null = A.null
      > end
      >

      Which really confuses me. Lets see the compile-time construction:
      A.null : simply an integer of value 0, should be possible
      B.null : = A.null = int with value 0, which should also be possible

      Why is it that the compiler cannot evaluate the above when the initial
      example worked? The above values "null" are not mutually recursive are they?

      In addition to the above, my problem is: B's data has a reference to A
      and A's data has a reference to B (basically to construct null values).

      > As explained in the manual, one of the modules must not define any value
      > which is not a function.

      I think you simplified this. Manual seems to say that I can have values
      but that they must be of type ty1 -> ty2. Could you elucidate me on why
      you limited this to functions and not values?


      > So that works:
      >
      > module rec A : sig val f : unit -> unit val null : int end =
      > struct
      > let f () = B.f ()
      > let null = 0
      > end
      > and B : sig val f : unit -> unit val null : unit -> int end =
      > struct
      > let f () = A.f ()
      > let null () = A.null
      > end
      >

      Basic difference between this example and the former is that B.null is
      now a function and is evaluated at run-time so construction is done at
      run-time. Once again I am confused as to why this works and the
      compile-time example (use of values) does not.

      Can you explain this?

      TIA,
      Hugo Ferreira.


      >
      >
      > Martin
      >
      > --
      > Martin Jambon, PhD
      > http://martin.jambon.free.fr
      >
      > Visit http://wikiomics.org, the Bioinformatics Howto Wiki
      >
      >
      > Archives up to August 22, 2005 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners/
      > The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
      > Attachments are banned and you're asked to be polite, avoid flames etc.
      > Yahoo! Groups Links
      >
      >
      >
      >
      >
      >
      >
    • Martin Jambon
      ... Too bad for you :-/ ... I think it s just that the compiler doesn t look that far. ... A function is a value anyway. A value whose type can be written as
      Message 2 of 10 , Mar 1, 2006
        On Wed, 1 Mar 2006, Hugo Ferreira wrote:

        > Hi Martin,
        >
        > Martin Jambon wrote:
        >> On Mon, 27 Feb 2006, Hugo Ferreira wrote:
        >>
        >>> The idea of using recursive modules was to split up the implementations
        > ...
        >> If you don't need to define mutually recursive non-functions, everything
        >> should be fine.
        >
        > This is the issue really. I have a mutually recursive data structures
        > and want to split them.

        Too bad for you :-/

        >> That works:
        >>
        >> module rec A : sig val f : unit -> unit end =
        >> struct
        >> let f () = B.f ()
        >> end
        >> and B : sig val f : unit -> unit end =
        >> struct
        >> let f () = A.f ()
        >> end
        >>
        >
        > Got this far but I need to define a data structure for the
        > implementation. (Above not really useful because we just have functions
        > that loop at runtime.)
        >
        >> And that doesn't work ("Cannot safely evaluate the definition of the
        >> recursively-defined module A"):
        >>
        >> module rec A : sig val f : unit -> unit val null : int end =
        >> struct
        >> let f () = B.f ()
        >> let null = 0
        >> end
        >> and B : sig val f : unit -> unit val null : int end =
        >> struct
        >> let f () = A.f ()
        >> let null = A.null
        >> end
        >>
        >
        > Which really confuses me. Lets see the compile-time construction:
        > A.null : simply an integer of value 0, should be possible
        > B.null : = A.null = int with value 0, which should also be possible

        I think it's just that the compiler doesn't look that far.

        > Why is it that the compiler cannot evaluate the above when the initial
        > example worked? The above values "null" are not mutually recursive are they?
        >
        > In addition to the above, my problem is: B's data has a reference to A
        > and A's data has a reference to B (basically to construct null values).
        >
        >> As explained in the manual, one of the modules must not define any value
        >> which is not a function.
        >
        > I think you simplified this. Manual seems to say that I can have values
        > but that they must be of type ty1 -> ty2. Could you elucidate me on why
        > you limited this to functions and not values?

        A function is a value anyway. A value whose type can be written as
        ty1 -> ty2 is a function.

        >> So that works:
        >>
        >> module rec A : sig val f : unit -> unit val null : int end =
        >> struct
        >> let f () = B.f ()
        >> let null = 0
        >> end
        >> and B : sig val f : unit -> unit val null : unit -> int end =
        >> struct
        >> let f () = A.f ()
        >> let null () = A.null
        >> end
        >>
        >
        > Basic difference between this example and the former is that B.null is
        > now a function and is evaluated at run-time so construction is done at
        > run-time. Once again I am confused as to why this works and the
        > compile-time example (use of values) does not.
        >
        > Can you explain this?

        It is just following the rule: there is now only one module (A) which
        defines values which are not of type ty1 -> ty2 (A.null). This excludes a
        number of cases which look simple but are rejected because of this, like
        our examples.

        But hey, even this rule doesn't guarantee safe definitions:

        module rec A :
        sig
        val f : unit -> unit -> unit
        val x : unit -> unit
        end =
        struct
        let f () =
        B.x ();
        fun () -> ()
        let x = f ()
        end
        and B :
        sig
        val f : unit -> unit -> unit
        val x : unit -> unit
        end =
        struct
        let f () =
        A.x ();
        fun () -> ()
        let x = f ()
        end
        ;;
        Exception: Undefined_recursive_module ("", 69, 0).



        --
        Martin Jambon, PhD
        http://martin.jambon.free.fr

        Visit http://wikiomics.org, the Bioinformatics Howto Wiki
      • Hugo Ferreira
        Martin Thanks for the feedback. Besides your example there is another one like yours in the bug tracking system (from 2004,
        Message 3 of 10 , Mar 1, 2006
          Martin

          Thanks for the feedback. Besides your example there is another one like
          yours in the bug tracking system (from 2004,
          http://caml.inria.fr/mantis/view.php?id=2629&nbn=3)

          I have the impression the recursive modules is unfinished work. 8-(

          Thanks,
          Hugo F.


          Martin Jambon wrote:
          > On Wed, 1 Mar 2006, Hugo Ferreira wrote:
          >
          >
          >>Hi Martin,
          >>
          >>Martin Jambon wrote:
          >>
          >>>On Mon, 27 Feb 2006, Hugo Ferreira wrote:
          >>>
          >>>
          >>>>The idea of using recursive modules was to split up the implementations
          >>
          >>...
          >>
          >>>If you don't need to define mutually recursive non-functions, everything
          >>>should be fine.
          >>
          >>This is the issue really. I have a mutually recursive data structures
          >>and want to split them.
          >
          >
          > Too bad for you :-/
          >
          >
          >>>That works:
          >>>
          >>>module rec A : sig val f : unit -> unit end =
          >>>struct
          >>> let f () = B.f ()
          >>>end
          >>>and B : sig val f : unit -> unit end =
          >>>struct
          >>> let f () = A.f ()
          >>>end
          >>>
          >>
          >>Got this far but I need to define a data structure for the
          >>implementation. (Above not really useful because we just have functions
          >>that loop at runtime.)
          >>
          >>
          >>>And that doesn't work ("Cannot safely evaluate the definition of the
          >>>recursively-defined module A"):
          >>>
          >>>module rec A : sig val f : unit -> unit val null : int end =
          >>>struct
          >>> let f () = B.f ()
          >>> let null = 0
          >>>end
          >>>and B : sig val f : unit -> unit val null : int end =
          >>>struct
          >>> let f () = A.f ()
          >>> let null = A.null
          >>>end
          >>>
          >>
          >>Which really confuses me. Lets see the compile-time construction:
          >>A.null : simply an integer of value 0, should be possible
          >>B.null : = A.null = int with value 0, which should also be possible
          >
          >
          > I think it's just that the compiler doesn't look that far.
          >
          >
          >>Why is it that the compiler cannot evaluate the above when the initial
          >>example worked? The above values "null" are not mutually recursive are they?
          >>
          >>In addition to the above, my problem is: B's data has a reference to A
          >>and A's data has a reference to B (basically to construct null values).
          >>
          >>
          >>>As explained in the manual, one of the modules must not define any value
          >>>which is not a function.
          >>
          >>I think you simplified this. Manual seems to say that I can have values
          >>but that they must be of type ty1 -> ty2. Could you elucidate me on why
          >>you limited this to functions and not values?
          >
          >
          > A function is a value anyway. A value whose type can be written as
          > ty1 -> ty2 is a function.
          >
          >
          >>>So that works:
          >>>
          >>>module rec A : sig val f : unit -> unit val null : int end =
          >>>struct
          >>> let f () = B.f ()
          >>> let null = 0
          >>>end
          >>>and B : sig val f : unit -> unit val null : unit -> int end =
          >>>struct
          >>> let f () = A.f ()
          >>> let null () = A.null
          >>>end
          >>>
          >>
          >>Basic difference between this example and the former is that B.null is
          >>now a function and is evaluated at run-time so construction is done at
          >>run-time. Once again I am confused as to why this works and the
          >>compile-time example (use of values) does not.
          >>
          >>Can you explain this?
          >
          >
          > It is just following the rule: there is now only one module (A) which
          > defines values which are not of type ty1 -> ty2 (A.null). This excludes a
          > number of cases which look simple but are rejected because of this, like
          > our examples.
          >
          > But hey, even this rule doesn't guarantee safe definitions:
          >
          > module rec A :
          > sig
          > val f : unit -> unit -> unit
          > val x : unit -> unit
          > end =
          > struct
          > let f () =
          > B.x ();
          > fun () -> ()
          > let x = f ()
          > end
          > and B :
          > sig
          > val f : unit -> unit -> unit
          > val x : unit -> unit
          > end =
          > struct
          > let f () =
          > A.x ();
          > fun () -> ()
          > let x = f ()
          > end
          > ;;
          > Exception: Undefined_recursive_module ("", 69, 0).
          >
          >
          >
          > --
          > Martin Jambon, PhD
          > http://martin.jambon.free.fr
          >
          > Visit http://wikiomics.org, the Bioinformatics Howto Wiki
          >
          >
          > Archives up to August 22, 2005 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners/
          > The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
          > Attachments are banned and you're asked to be polite, avoid flames etc.
          > Yahoo! Groups Links
          >
          >
          >
          >
          >
          >
          >
          >
        Your message has been successfully submitted and would be delivered to recipients shortly.