4

I am new in OCaml and I wrote some code to get the n element of a list

let rec n_elem l n = match n with
| 0 -> match l with
    | h::_ -> h
    | _ -> failwith "erorr with empty list"
| _ -> match l with
    | h::t -> n_elem t (n-1)
    | _ -> failwith "erorr with empty list"
;;

When I run it using ocaml interpreter, an warning generate as:

Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
1
Warning 11: this match case is unused.

and when I run it with:

Printf.printf "%s\n" (n_elem ["a";"b";"c";"d"] 1);;

it generate match_failure...

Could anyone give me some help?

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
lllllllllllll
  • 8,519
  • 9
  • 45
  • 80

2 Answers2

6

This is basically a precedence problem. The second _ match case is part of the second match expression. You can use begin/end to keep them separate:

let rec n_elem l n = match n with
| 0 -> 
    begin
    match l with
    | h::_ -> h
    | _ -> failwith "erorr with empty list"
    end
| _ ->
    begin
     match l with
    | h::t -> n_elem t (n-1)
    | _ -> failwith "erorr with empty list"
    end
Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108
0

In addition to what Jeffrey has very correctly pointed out, it's unnecessary to have nested match expressions here. Rather we can match on a tuple of n and l.

This also lets us avoid duplication of code (the same exception being raised twice).

let rec n_elem l n = 
  match n, l with
  | 0, h::_ -> h
  | _, _::t -> n_elem t (n-1)
  | [], _ -> failwith "error with empty list"
Chris
  • 26,361
  • 5
  • 21
  • 42