Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I split an OCaml list into head and tail?

I'm just learning OCaml and right now, I use match l with h::t -> to split lists when I need to access the head. But I'm sure there has to be a better way to split a list this way. I can't seem to find much online. Maybe I'm not looking in the right way.

like image 441
Antrikshy Avatar asked Oct 15 '25 14:10

Antrikshy


2 Answers

It's the best way.

There are functions List.hd and List.tl to get hd and tl but there is no function available in the standard library to get the head and tail in one move. In addition List.hd and List.tl are unsafe: if you give an empty list to them, they raise runtime exceptions:

# List.hd [];;
Exception: Failure "hd".

You can use them safely if you are 100% sure that the argument cannot be empty, but your speculation is often not correct in practice. List.hd and tl can be very good sources of bugs.

Using patterns with let: let (h::t) = l in ... is possible, but it also has a risk of runtime failures, but the compiler can tell you that your pattern is not exhaustive and lacks the handling of [].

match can have multiple cases and you can cover the case for []: match l with [] -> ... | (h::t) -> .... If you forget the case for [], the compiler can warn you about it.

like image 183
camlspotter Avatar answered Oct 18 '25 06:10

camlspotter


The OCaml way for this issue is the expression

match l with
| [] -> some_expr
| x :: xs -> some_other_expr
  • The worst solution is using List.hd or List.hd, leading to possible runtime exception.

  • The second worse solution is an incomplete match such as match l with x :: xs leading also to the same runtime errors, but you at least get a compile time warning, with the matching case(s) you missed.

Note that you can ignore some parts of the matching if not used, so your code is self documenting:

let hd_option lst =
match lst with
| [] -> None
| x :: _ -> Some x (* the tail is not used, so I just don't name it *)
like image 33
mookid Avatar answered Oct 18 '25 06:10

mookid



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!