Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OCaml function parameter pattern matching for strings

Tags:

ocaml

I tried to pass a string in to get a reversed string. Why can't I do this:

let rec reverse x = 
  match x with
  | "" -> ""
  | e ^ s -> (reverse s) ^ e;;

The compiler says it's a syntax error. Can't I use ^ to destructure parameters?

like image 707
lkahtz Avatar asked Mar 25 '12 18:03

lkahtz


People also ask

How do I match a string in OCaml?

There is a way to match strings as a list of characters, using a function from SML (which you can write in OCaml) called 'explode' and 'implode' which --respectively -- take a string to a char list and vice versa.

How does pattern matching work in OCaml?

Pattern matching comes up in several places in OCaml: as a powerful control structure combining a multi-armed conditional, unification, data destructuring and variable binding; as a shortcut way of defining functions by case analysis; and as a way of handling exceptions.

What does :: do in OCaml?

Regarding the :: symbol - as already mentioned, it is used to create lists from a single element and a list ( 1::[2;3] creates a list [1;2;3] ).

What is a tuple in OCaml?

Every function in OCaml takes exactly one value and returns exactly one result. For instance, our squareRoot function takes one float value and returns one float value. The advantage of always taking one argument and returning one result is that the language is extremely uniform.


1 Answers

When you write a pattern matching expression, you cannot use arbitrary functions in your patterns. You can only use constructors, which look like unevaluated functions. For example, the function "+" is defined on integers. So the expression 1+2 is evaluated and gives 3; the function "+" is evaluated, so you cannot match on x+y. Here is an attempt to define a function on natural numbers that checks whether the number is zero:

 let f x =  match x with
  | 0 -> false
  | a+1 -> true
 ;;

This cannot work! For the same reason, your example with strings cannot work. The function "^" is evaluated on strings, it is not a constructor.

The matching on x+1 would work only if numbers were unevaluated symbolic expressions made out of the unevaluated operator + and a symbolic constant 1. This is not the case in OCAML. Integers are implemented directly through machine numbers.

When you match a variant type, you match on constructors, which are unevaluated expressions. For example:

 # let f x = match x with
    | Some x -> x+1
    | None -> 0
 ;;
 val f : int option -> int = <fun>

This works because the 'a option type is made out of a symbolic expression, such as Some x. Here, Some is not a function that is evaluated and gives some other value, but rather a "constructor", which you can think of as a function that is never evaluated. The expression Some 3 is not evaluated any further; it remains as it is. It is only on such functions that you can pattern-match.

Lists are also symbolic, unevaluated expressions built out of constructors; the constructor is ::. The result of x :: y :: [] is an unevaluated expression, which is represented by the list [x;y] only for cosmetic convenience. For this reason, you can pattern-match on lists.

like image 195
winitzki Avatar answered Oct 13 '22 01:10

winitzki