According to this article , there really is that exact example that you are discussing:
As we saw, the list can be either empty (the list has the form [] ), or consists of the first element (its head) and a sublist (its tail). Then the list has the form h::t .
The above statement simply gives you 0 if the list matches an empty list or uses pattern matching to extract the head (first element) and tail (all other elements), and then uses recursion to get the length of the tail.
So this is _::tail , which reduces the list, and 1 + (size tail) , which calculates the size. Bit before | is, of course, the condition for completing the recursion.
This may be more understandable (in my opinion) when viewed as:
let rec size x = match x with [] -> 0 | _::tail -> 1 + (size tail) ;;
(actually it is very similar to the format used on the linked page, I changed it a bit to align the characters -> ).
source share