ocaml-batteries-team/batteries-included — pull request #555 by gasche (2014-03-27 09:29:03+00:00)
Title: batList.{modify_at,modify_opt_at}: modify values at a given list position

on #ocaml early this morning:

> 02:23 < morolin> Is there a good way to write a function that takes a list and an integer (n) as an input, and returns a list with the nth element modifed in some way?
> 02:24 < morolin> I'd rather avoid using fold_left, since in most cases, I will be modifying elements from the beginning of the list
> 02:24 < morolin> Looking at the "List" module, I see "nth" which will let me get the nth element, but nothing that'll let me replace it.
> 02:25 < morolin> I.e., I would like to have a function whose type is: 'a list -> int -> ('a -> 'a) -> 'a list

"Of course, it is in Batteries". Almost.

To be honest I'm extremely confident in `modify_at`, but slightly less
about `modify_opt_at`. On one hand, it is an obvious generalization,
on the other the difference with respect to `modify_opt` (we only
support returning an option, not taking an option as input, as
extending a list at arbitrary indices makes no sense) makes it
slightly less satisfying.

Do you have warm feelings about `modify_opt_at`, or should we
(over-)cautiously leave it out?

Note that the failure mode is to raise `Invalid_argument`, like all
the `*_at` functions, instead of `Not_found` as all the `modify_*`
functions. I think it is the better choice, but users might assume the
other way. My reasoning is as follows: accessing-by-index
a fixed-length data-structure is much less flexible than
accessing-by-key an associative data-structure and notably, users are
supposed to have already checked the index before calling the
function, so the error is not supposed to get caught -- so it's ok if
it's one of those lousy string-taking exceptions.