OCaml Adds List.take
and List.drop
One of my small issues with OCaml is that the standard library is quite spartan.
Sometimes it misses functions that are quite common in other (similar)
languages. One such example are functions like drop
, drop_while
, take
and
take_while
in the List module.1 What’s weird is that the similar
Seq module features all those functions
since OCaml 4.14.
Fortunately, that’s finally changing! While perusing the OCaml
changelog a few days ago, I
noticed a reference to a recently merged pull
request that adds the missing List
functions. It’s interesting that this PR is a follow-up to another PR that was a
bit more ambitious and was created way back in Oct
2020. Oh, well - better late than
never, right?
As you can imagine there’s nothing fancy about the implementation of the new functions:
let take n l =
let[@tail_mod_cons] rec aux n l =
match n, l with
| 0, _ | _, [] -> []
| n, x::l -> x::aux (n - 1) l
in
if n < 0 then invalid_arg "List.take";
aux n l
let drop n l =
let rec aux i = function
| _x::l when i < n -> aux (i + 1) l
| rest -> rest
in
if n < 0 then invalid_arg "List.drop";
aux 0 l
let take_while p l =
let[@tail_mod_cons] rec aux = function
| x::l when p x -> x::aux l
| _rest -> []
in
aux l
let rec drop_while p = function
| x::l when p x -> drop_while p l
| rest -> rest
Pretty standard recursive implementations. If you’re not familiar with
@tail_mod_cons
- it’s basically tail-call optimization for ::
(a.k.a. cons
)
in the final position of a recursive function.2
It seems the new List
functions will be shipped with OCaml 5.3. OCaml 5.2 is
not out at the time I’m writing this, but I’m guessing the PR missed the merge
window for 5.2. In the mean time - we can continue to rely on the excellent
Containers
library
for that functionality.
That’s all I have for you today. Keep hacking!
-
I believe it was Haskell that populirized them. ↩
-
See https://v2.ocaml.org/manual/tail_mod_cons.html for more details. ↩