Как я могу пропустить термин со Списком. Карта в OCAML?

Предположим, что у меня есть некоторый код как это:

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

Существует ли способ сделать это? Если так, как?

Я хочу и управлять объектом, если он соответствует некоторым критериям, и проигнорируйте его, если он не делает. Таким образом List.filter, казалось бы, не был бы решением.

10
задан Steve Rowe 8 July 2010 в 09:17
поделиться

3 ответа

В SML есть функция mapPartial, которая делает именно это. К сожалению, в OCaml такой функции не существует. Однако вы можете легко определить ее самостоятельно, например, так:

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)

Использование:

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

вернет [1;3;4].

Или вы можете использовать filter_map из extlib, как указал ygrek.

13
ответ дан 3 December 2019 в 15:05
поделиться

В качестве альтернативы вы можете отфильтровать список и применить карту к полученному списку следующим образом :

let map_bis predicate map_function lst =
    List.map map_function (List.filter predicate lst);;

# val map_bis : ('a -> bool) -> ('a -> 'b) -> 'a list -> 'b list = <fun>

Использование:

# map_bis (fun e -> e<>1) (fun e -> e+1) [0;1;2;3];;
- : int list = [1; 3; 4]
4
ответ дан 3 December 2019 в 15:05
поделиться

Оба Batteries и Extlib предоставляют эквивалент mapPartial : их расширенный модуль List обеспечивает filter_map функция типа ('a ->' b option) -> 'a list ->' b list , позволяющая функции карты также выбирать элементы.

7
ответ дан 3 December 2019 в 15:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: