2

I want to build a list of type (char, 'a list) list where each char is an upper case letter of the alphabet. I'am getting a warning Warning 11: this match case is unused. for the second match case on get_list. I did some prints on the first case and found out len get's there with value 0, so it never uses the second case. What's happening?

let rec get_list abc i len = 
  match i with 
  | len -> []
  | _ -> ((String.get abc i), [])::get_list abc (i + 1) len

in

let rec print_list l = 
  match l with
  | [] -> ()
  | h::t -> print_char(fst h);print_list t
in

let abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" in
let abc_l = get_list abc 0 (String.length abc) in
print_list abc_l;;
power_output
  • 411
  • 10
  • 26
  • I'd use the `if ... then ... else ...` expression instead of pattern-matching on integers -- it conveys sense to the reader much faster and not so error-prone. – Anton Trunov May 01 '16 at 15:18

2 Answers2

2

The reason it doesn't work

When you write

match i with 
  | len -> []
  | _ -> ["..."]

len is a generic pattern, which hasn't anything to do with the len define above. In a pattern matching you define only how the variable should look like, you describe it's general "structure", the variable names are used to name the differents parts of the pattern matching, and are new variables. For example with lists you can do:

match my_list with 
  | [x,y,z] -> x+y+z
  | x :: r  -> x + (List.length r)
  | anything_else -> List.length anything_else

When you put '_' it's only a convention to say "I don't mind which value it is, I don't need it". Here is another example with tuples:

match my_tuple with 
  | (a,b) -> a+b

A solution : conditionnal pattern matching

If you want to put condition in a pattern matching you can use the when keyword :

match i with 
  | n when n = len -> []
  | _ -> ["..."]

Another example that "sort" a tuple:

match my_tuple with 
  | (a,b) when a>b -> (a,b)
  | (a,b)          -> (b,a)

Or just use conditions with integers :

if i = len then []
else ["..."]

You can also note that you can do pattern matching within functions :

let f (a,b) = a+b
tobiasBora
  • 1,542
  • 14
  • 23
0

The len in your pattern is a new variable introduced by the pattern. As a pattern, its meaning is that it will match anything at all. Thus, the next pattern _ will never match.

As @AlexanderRevyakin says, this new variable len is hiding the parameter that's also named len.

It is not the case that the len in your pattern represents the value of the parameter len. OCaml patterns contain only new variables (to which pieces of the matched value are bound) and constants. They don't contain expressions that are evaluated at run time. For that you want to use if/then/else (as @AntonTrunov points out).

Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108