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

Pattern matching on arrays

Expand Messages
  • deech_99
    Ocaml offers pattern matching on arrays, but it doesn t seem to behave like list pattern-matching. For instance, the following, where x is the first element
    Message 1 of 4 , Nov 30, 2008
      Ocaml offers pattern matching on arrays, but it doesn't seem to behave
      like list pattern-matching.

      For instance, the following, where 'x' is the first element and '_' is
      the rest of the array doesn't work:
      # match [|1;2;3|] with [|x;_|] -> x;;

      Characters 0-33:

      match [|1;2;3|] with [|x;_|] -> x;;

      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

      Warning P: this pattern-matching is not exhaustive.

      Here is an example of a value that is not matched:

      [| |]

      Exception: Match_failure ("", 100, -408).

      Is there some way to do this in Ocaml?
      -deech
    • deech_99
      The only solution I can come up with is to convert the array to a list and then pattern-match like so: match (Array.to_list [|1;2;3|]) with x :: [] - x ...
      Message 2 of 4 , Nov 30, 2008
        The only solution I can come up with is to convert the array to a list
        and then pattern-match like so:
        match (Array.to_list [|1;2;3|]) with
        x :: [] -> x
        |[] -> -1

        But this doesn't seem particularly efficient or elegant.

        -deech

        --- In ocaml_beginners@yahoogroups.com, "deech_99" <deech_99@...> wrote:
        >
        > Ocaml offers pattern matching on arrays, but it doesn't seem to behave
        > like list pattern-matching.
        >
        > For instance, the following, where 'x' is the first element and '_' is
        > the rest of the array doesn't work:
        > # match [|1;2;3|] with [|x;_|] -> x;;
        >
        > Characters 0-33:
        >
        > match [|1;2;3|] with [|x;_|] -> x;;
        >
        > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        >
        > Warning P: this pattern-matching is not exhaustive.
        >
        > Here is an example of a value that is not matched:
        >
        > [| |]
        >
        > Exception: Match_failure ("", 100, -408).
        >
        > Is there some way to do this in Ocaml?
        > -deech
        >
      • Florent Monnier
        ... here you are trying to make match together an array with 3 elements with another array of only 2 elements. another point is that the length of an array is
        Message 3 of 4 , Nov 30, 2008
          > match [|1;2;3|] with [|x;_|] -> x;;

          here you are trying to make match together an array with 3 elements
          with another array of only 2 elements.

          another point is that the length of an array is an information which is
          totally absent from the type system, so if you do this :

          # match [|1;2;3|] with
          | [|x;_|] -> x
          | _ -> 0
          ;;
          - : int = 0

          it does infere properly but the default glob case handles the array.

          if you handle properly an array of length 3 in the cases, you still have to
          put a default case in order to avoid a warning:

          # match [|1;2;3|] with
          | [|x;_;_|] -> x
          | _ -> 0
          ;;
          - : int = 1

          --
          Cheers
          Florent
        • Richard Jones
          ... You can t do what you want to do. The representation of lists (as singly-linked lists) allows you to write: match xs with x :: _ - x because that matches
          Message 4 of 4 , Dec 1, 2008
            On Mon, Dec 01, 2008 at 12:33:31AM -0000, deech_99 wrote:
            > Ocaml offers pattern matching on arrays, but it doesn't seem to behave
            > like list pattern-matching.
            >
            > For instance, the following, where 'x' is the first element and '_' is
            > the rest of the array doesn't work:
            > # match [|1;2;3|] with [|x;_|] -> x;;

            You can't do what you want to do.

            The representation of lists (as singly-linked lists) allows you to
            write:

            match xs with x :: _ -> x

            because that matches on the first cell of the list and binds 'x' to
            the head and '_' to the tail. In C the equivalent would be:

            struct list {
            void *elem; /* bound to 'x' */
            struct list *next; /* bound to '_' */
            };

            Arrays are represented as a flat array of elements in memory (just
            like arrays in C). There is no head or tail of an array, only
            elements. Thus:

            match as with [| x; y |] -> ...

            matches a two element array and binds 'x' to the first element and 'y'
            to the second element. There is no constructor pattern-matching form
            as with lists because there is no constructor / cons cell involved in
            the representation.

            Rich.

            --
            Richard Jones
            Red Hat
          Your message has been successfully submitted and would be delivered to recipients shortly.