Search code examples
ocaml

How can I skip a term with List.Map in OCAML?


Suppose I have some code like this:

List.map (fun e -> if (e <> 1) then e + 1 else (*add nothing to the list*))

Is there a way to do this? If so, how?

I want to both manipulate the item if it matches some criteria and ignore it if it does not. Thus List.filter wouldn't seem to be the solution.


Solution

  • SML has a function mapPartial which does exactly this. Sadly this function does not exist in OCaml. However you can easily define it yourself like this:

    let map_partial f xs =
      let prepend_option x xs = match x with
      | None -> xs
      | Some x -> x :: xs in
      List.rev (List.fold_left (fun acc x -> prepend_option (f x) acc) [] xs)
    

    Usage:

    map_partial (fun x -> if x <> 1 then Some (x+1) else None) [0;1;2;3]
    

    will return [1;3;4].

    Or you can use filter_map from extlib as ygrek pointed out.