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

Re: "ocaml_beginners"::[] Re: Using variant type for indexing an array

Expand Messages
  • Lukasz Stafiniak
    ... No, it wouldn t. [ref] is a function, [ref 0] creates a new reference cell the time it is computed. So, we need to create the reference cells when defining
    Message 1 of 28 , Jan 5, 2009
    • 0 Attachment
      On Mon, Jan 5, 2009 at 9:04 PM, Cedric Cellier <rixed@...> wrote:
      > -[ Mon, Jan 05, 2009 at 08:36:51PM +0100, Lukasz Stafiniak ]----
      >
      >> > let fruits_count f = match f with
      >> > | APPLE -> ref 0
      >> > | ORANGE -> ref 0
      >> > | BANANA -> ref 5
      >> > ;;
      >>
      >> let fruits_count =
      >> let r1, r2, r3 = ref 0, ref 0, ref 5 in
      >> function
      >> | APPLE -> r1
      >> | ORANGE -> r2
      >> | BANANA -> r3
      >> ;;
      >
      > I don't get the difference, Wouldn't the first fruits_count
      > return the same ref if called several times for the same fruit ?
      >
      No, it wouldn't. [ref] is a function, [ref 0] creates a new reference
      cell the time it is computed.
      So, we need to create the reference cells when defining the function,
      not inside the function body.
    • Jon Harrop
      ... No. The expression ref x creates a new reference to x so the first variant returns you a new reference to the same constant every time you call it. --
      Message 2 of 28 , Jan 5, 2009
      • 0 Attachment
        On Monday 05 January 2009 20:04:10 Cedric Cellier wrote:
        > -[ Mon, Jan 05, 2009 at 08:36:51PM +0100, Lukasz Stafiniak ]----
        > > > let fruits_count f = match f with
        > > >
        > > > | APPLE -> ref 0
        > > > | ORANGE -> ref 0
        > > > | BANANA -> ref 5
        > > >
        > > > ;;
        > >
        > > let fruits_count =
        > > let r1, r2, r3 = ref 0, ref 0, ref 5 in
        > > function
        > >
        > > | APPLE -> r1
        > > | ORANGE -> r2
        > > | BANANA -> r3
        > >
        > > ;;
        >
        > I don't get the difference, Wouldn't the first fruits_count
        > return the same ref if called several times for the same fruit ?

        No. The expression "ref x" creates a new reference to "x" so the first variant
        returns you a new reference to the same constant every time you call it.

        --
        Dr Jon Harrop, Flying Frog Consultancy Ltd.
        http://www.ffconsultancy.com/?e
      • j.romildo@gmail.com
        On Mon, Jan 05, 2009 at 12:44:35PM +0000, Richard Jones wrote: [...] ... Would you enhance the enum extension to include conversion functions from string and
        Message 3 of 28 , Jun 2, 2009
        • 0 Attachment
          On Mon, Jan 05, 2009 at 12:44:35PM +0000, Richard Jones wrote:
          [...]
          > Attached is an example of an 'enum' camlp4 extension.
          >
          > As discussed previously, you can write:
          >
          > enum fruits = Apple | Banana | Orange
          >
          > and the following code is automagically generated for you:
          >
          > type fruits = Apple | Banana | Orange
          > let fruits_max = 3

          Would you enhance the enum extension to include conversion functions
          from string and to string. Something like the following for the given
          example

          let string_to_fruits = function
          | "Apple" -> Apple
          | "Banana" -> Banana
          | "Orange" -> Orange
          | str -> raise (Invalid_argument ("string_to_fruit: " ^
          "invalid fruits name: " ^ str))

          let fruits_to_string = function
          | Apple -> "Apple"
          | Banana -> "Banana"
          | Orange -> "Orange"

          If I had any experience with camlp I would do it myself.

          Regards,

          José Romildo
        • Martin Jambon
          ... It s actually camlp4, like Ocean s Eleven. :-) Martin -- http://mjambon.com/
          Message 4 of 28 , Jun 2, 2009
          • 0 Attachment
            j.romildo@... wrote:

            > If I had any experience with camlp I would do it myself.

            It's actually camlp4, like Ocean's Eleven. :-)


            Martin

            --
            http://mjambon.com/
          • j.romildo@gmail.com
            ... After reading some of the tutorials on camlp4 (and not understanding much of them), I was able to implement the enhancements sugested above to the enum
            Message 5 of 28 , Jun 2, 2009
            • 0 Attachment
              On Tue, Jun 02, 2009 at 10:03:56AM -0300, j.romildo@... wrote:
              > On Mon, Jan 05, 2009 at 12:44:35PM +0000, Richard Jones wrote:
              > [...]
              > > Attached is an example of an 'enum' camlp4 extension.
              > >
              > > As discussed previously, you can write:
              > >
              > > enum fruits = Apple | Banana | Orange
              > >
              > > and the following code is automagically generated for you:
              > >
              > > type fruits = Apple | Banana | Orange
              > > let fruits_max = 3
              >
              > Would you enhance the enum extension to include conversion functions
              > from string and to string. Something like the following for the given
              > example
              >
              > let string_to_fruits = function
              > | "Apple" -> Apple
              > | "Banana" -> Banana
              > | "Orange" -> Orange
              > | str -> raise (Invalid_argument ("string_to_fruit: " ^
              > "invalid fruits name: " ^ str))
              >
              > let fruits_to_string = function
              > | Apple -> "Apple"
              > | Banana -> "Banana"
              > | Orange -> "Orange"
              >
              > If I had any experience with camlp I would do it myself.

              After reading some of the tutorials on camlp4 (and not understanding
              much of them), I was able to implement the enhancements sugested above
              to the enum extension tha has been made available by Richard Jones at
              the url http://www.annexia.org/tmp/enum/.

              I am attaching a patch for review.

              If it is good enough, maybe Richard Jones could integrate it to the
              original source.

              Regarads
              --
              Prof. José Romildo Malaquias
              Computer Science Department
              Federal University of Ouro Preto
              Brazil

              ----------

              diff -ur enum.orig/pa_enum.ml enum/pa_enum.ml
              --- enum.orig/pa_enum.ml 2009-01-05 10:47:14.000000000 -0200
              +++ enum/pa_enum.ml 2009-06-03 00:07:15.000000000 -0300
              @@ -29,7 +29,8 @@

              (* 'tds' is a list of type declarations, each of which must be a
              * simple variant with no parameters. This checks them and returns
              - * corresponding 'typename_max' definitions.
              + * corresponding 'typename_max', 'typename_to_string' and
              + * 'string_to_typename' definitions.
              *)
              let rec generate_strs _loc tds =
              let types = check_tds _loc tds in
              @@ -38,20 +39,40 @@
              fun (name, fields) strs ->
              let nr_fields = List.length fields in
              let name_max = name ^ "_max" in
              - <:str_item< let $lid:name_max$ = $`int:nr_fields$ ;; $strs$ >>
              + let strs1 = <:str_item< let $lid:name_max$ = $`int:nr_fields$ ;; $strs$ >> in
              + let name_to_string = name ^ "_to_string" in
              + let cases =
              + List.fold_left (
              + fun strs field ->
              + <:match_case< $strs$ | $uid:field$ -> $str:field$ >>
              + ) <:match_case< >> fields
              + in
              + let strs2 = <:str_item< $strs1$ ;; let $lid:name_to_string$ = function $cases$ >> in
              + let string_to_name = "string_to_" ^ name in
              + let cases =
              + List.fold_right (
              + fun field strs ->
              + <:match_case< $str:field$ -> $uid:field$ | $strs$ >>
              + ) fields <:match_case< _ -> raise (Invalid_argument $str:string_to_name$) >>
              + in
              + let strs3 = <:str_item< $strs2$ ;; let $lid:string_to_name$ = function $cases$ >> in
              + strs3
              ) types <:str_item< >>

              (* 'tds' is a list of type declarations, each of which must be a
              * simple variant with no parameters. This checks them and returns
              - * corresponding 'typename_max' signatures.
              + * corresponding 'typename_max', 'typename_to_string' and
              + * 'string_to_typename' signatures.
              *)
              and generate_sigs _loc tds =
              let types = check_tds _loc tds in
              (*print_types types; (* for debugging *)*)
              List.fold_right (
              fun (name, _) sigs ->
              - let name_max = name ^ "_max" in
              - <:sig_item< val $lid:name_max$ : int ;; $sigs$ >>
              + let sigs1 = <:sig_item< val $lid:name ^ "_to_string"$ : $lid:name$ -> string ;; $sigs$ >> in
              + let sigs2 = <:sig_item< val $lid:"string_to_" ^ name$ : string -> $lid:name$ ;; $sigs1$ >> in
              + let sigs3 = <:sig_item< val $lid:name ^ "_max"$ : int ;; $sigs2$ >> in
              + sigs3
              ) types <:sig_item< >>

              (* Check that the type definitions are all simple variants with no
              diff -ur enum.orig/test_enum.ml enum/test_enum.ml
              --- enum.orig/test_enum.ml 2009-01-05 10:47:25.000000000 -0200
              +++ enum/test_enum.ml 2009-06-03 00:23:11.000000000 -0300
              @@ -6,4 +6,7 @@

              let () =
              printf "there are %d fruits, %d vegetables and %d legumes\n"
              - fruits_max vegetables_max legumes_max
              + fruits_max vegetables_max legumes_max;
              + printf "%s\n" (fruits_to_string Banana);
              + printf "%s\n" (fruits_to_string (string_to_fruits "Orange"));
              + printf "%s\n" (fruits_to_string (string_to_fruits "Strawberry"))


              [Non-text portions of this message have been removed]
            Your message has been successfully submitted and would be delivered to recipients shortly.