Wildcards in pattern-matching / recursive function

The tutorial I’m following has the following example code for a recursive function that uses pattern matching to return the length of a list

# let rec length u =
    match u with
    | [] -> 0
    | _ :: v -> 1 + length v;;
val length : 'a list -> int = <fun>

Which I read as 'empty list has length zero, things that look like an element cons’d onto a list have length 1 + the length of the sub-list.

In imitation of this, I tried to write a function that returns a string that is the concatenation of all elements in the list.

let rec glom u = 
match u with 
| [] -> ""
| _ :: v -> _ :: glom v;;
Error: Syntax error: wildcard "_" not expected

so it seems like the special character _ can stand for ‘any element’ in the pattern _ :: v to mean “looks like an element cons’d onto a list” but it’s not available as “element that matched”

Is this sort of thing possible in this context? If this were Perl (please don’t throw things) I guess you’d use $1 to get ‘the thing that matched’

First, you can name the head of the list as you wish, for instance s:

let rec glom u =
  match u with
  | [] -> ""
  | s :: v -> s :: glom v

But then, you’ll get the following error:

$ ocaml tmp.ml
File "./tmp.ml", line 4, characters 14-25:
4 |   | s :: v -> s :: glom v
                  ^^^^^^^^^^^
Error: This expression has type 'a list
       but an expression was expected of type string

This is because :: is a constructor for lists.

What you want is the ^ operator that concatenates two strings:

let rec glom u =
  match u with
  | [] -> ""
  | s :: v -> s ^ glom v

But note that this is pretty inefficient.

3 Likes

Thanks very much; in retrospect I should have realized I wanted ^ and not ::