Remove our custom `Option` module and use the new stdlib one instead. Use the new `List.filter_map` from the stdlib instead of our one. Also, rename our `first_match` to `find_map`, to match the name in 4.10.
···291291 if starts_with vexpr pre then Some vexpr else None in
292292 let all_versions = Feed.zi_implementations feed
293293 |> XString.Map.map_bindings (fun _k impl -> impl.Impl.parsed_version) in
294294- let matching_versions = Support.Utils.filter_map check (List.sort compare all_versions) in
294294+ let matching_versions = List.filter_map check (List.sort compare all_versions) in
295295 List.iter (completer#add Add) matching_versions
296296297297(* 0install --option=<Tab> *)
···1919 let not_before = ref None in
20202121 (* Handle --before, --not-before and --version by converting to --version-for options *)
2222- let options = options |> Support.Utils.filter_map (function
2222+ let options = options |> List.filter_map (function
2323 | `Before v -> before := Some v; None
2424 | `NotBefore v -> not_before := Some v; None
2525 | `RequireVersion v -> Some (`RequireVersionFor (default_iface, v))
+1-1
src/cli/store.ml
···7676 | [] -> config.stores
7777 | dirs -> dirs in
78787979- let audit_ls = dirs |> U.filter_map (fun dir ->
7979+ let audit_ls = dirs |> List.filter_map (fun dir ->
8080 if U.is_dir system dir then Some (
8181 let items =
8282 match system#readdir dir with
+1-1
src/gui_gtk/trust_box.ml
···258258259259 dialog#connect#response ==> (function
260260 | `OK ->
261261- let to_trust = !trust_checkboxes |> U.filter_map (fun (fpr, box) ->
261261+ let to_trust = !trust_checkboxes |> List.filter_map (fun (fpr, box) ->
262262 if box#active then Some fpr else None
263263 ) in
264264 assert (to_trust <> []);
+3-4
src/solver/diagnostics.ml
···55(** Explaining why a solve failed or gave an unexpected answer. *)
6677module List = Solver_core.List
88-module Option = Solver_core.Option
98109let pf = Format.fprintf
1110···223222 let check_restriction r =
224223 if Model.meets_restriction dep_impl r then None
225224 else Some (`DepFailsRestriction (dep, r)) in
226226- List.first_match check_restriction (Model.restrictions dep) in
225225+ List.find_map check_restriction (Model.restrictions dep) in
227226 let deps, commands_needed = Model.requires role impl in
228228- commands_needed |> List.first_match (fun command ->
227227+ commands_needed |> List.find_map (fun command ->
229228 if Model.get_command impl command <> None then None
230229 else Some (`MissingCommand command : Note.rejection_reason)
231230 )
232231 |> function
233232 | Some _ as r -> r
234234- | None -> List.first_match check_dep deps
233233+ | None -> List.find_map check_dep deps
235234236235 (** A selected component has [dep] as a dependency. Use this to explain why some implementations
237236 of the required interface were rejected. *)
+5-27
src/solver/solver_core.ml
···4455(** Select a compatible set of components to run a program. *)
6677-module Option = struct
88- let iter f = function
99- | None -> ()
1010- | Some x -> f x
1111-1212- let bind x f =
1313- match x with
1414- | None -> None
1515- | Some x -> f x
1616-1717- let map f = function
1818- | None -> None
1919- | Some x -> Some (f x)
2020-end
2121-227module List = struct
238 include List
2492525- let rec filter_map fn = function
2626- | [] -> []
2727- | (x::xs) ->
2828- match fn x with
2929- | None -> filter_map fn xs
3030- | Some y -> y :: filter_map fn xs
3131-3232- let rec first_match f = function
1010+ let rec find_map f = function
3311 | [] -> None
3412 | (x::xs) -> match f x with
3513 | Some _ as result -> result
3636- | None -> first_match f xs
1414+ | None -> find_map f xs
3715end
38163917type ('a, 'b) partition_result =
···580558 | Selected (deps, self_commands) ->
581559 (* We've already selected a candidate for this component. Now check its dependencies. *)
582560 let check_self_command name = find_undecided {req with Model.command = Some name} in
583583- match List.first_match check_self_command self_commands with
561561+ match List.find_map check_self_command self_commands with
584562 | Some _ as r -> r
585563 | None ->
586564 (* Self-commands already done; now try the dependencies *)
···598576 | None ->
599577 (* Command dependencies next *)
600578 let check_command_dep name = find_undecided {Model.command = Some name; role = dep_role} in
601601- List.first_match check_command_dep dep_required_commands
579579+ List.find_map check_command_dep dep_required_commands
602580 )
603581 in
604604- match List.first_match check_dep deps with
582582+ match List.find_map check_dep deps with
605583 | Some _ as r -> r
606584 | None ->
607585 (* All dependencies checked; now to the impl (if we're a <command>) *)
+1-1
src/support/argparse.ml
···261261262262let pp_options format_type fmt opts =
263263 let display_options =
264264- opts |> Utils.filter_map (fun (names, (nargs:int), help, p) ->
264264+ opts |> List.filter_map (fun (names, (nargs:int), help, p) ->
265265 match help with
266266 | "" -> None
267267 | help ->
+1-1
src/support/gpg.ml
···199199200200(** Parse the status output from gpg as a list of signatures. *)
201201let sigs_from_gpg_status_output status =
202202- status |> Str.split re_newline |> U.filter_map (fun line ->
202202+ status |> Str.split re_newline |> List.filter_map (fun line ->
203203 if XString.starts_with line "[GNUPG:] " then (
204204 match XString.tail line 9 |> Str.split_delim XString.re_space with
205205 | [] -> None
+1-1
src/support/locale.ml
···5555 | Some langs -> Str.split XString.re_colon langs
5656 | None -> [lang]
5757 ) in
5858- let specs = Utils.filter_map parse_lang langs in
5858+ let specs = List.filter_map parse_lang langs in
5959 if List.mem default specs then specs else specs @ [default]
60606161(* Converts a list of languages (most preferred first) to a map from languages to scores.
+1-7
src/support/utils.ml
···4040 Logging.dump_crash_log ~ex ();
4141 exit 1
42424343+(* Replace with [List.find_map] once we require OCaml >= 4.10 *)
4344let rec first_match f = function
4445 | [] -> None
4546 | (x::xs) -> match f x with
4647 | Some _ as result -> result
4748 | None -> first_match f xs
4848-4949-let rec filter_map fn = function
5050- | [] -> []
5151- | (x::xs) ->
5252- match fn x with
5353- | None -> filter_map fn xs
5454- | Some y -> y :: filter_map fn xs
55495650let filter_map_array fn arr =
5751 let result = ref [] in
-3
src/support/utils.mli
···1919val first_match : ('a -> 'b option) -> 'a list -> 'b option
20202121(** List the non-None results of [fn item] *)
2222-val filter_map : ('a -> 'b option) -> 'a list -> 'b list
2323-2424-(** List the non-None results of [fn item] *)
2522val filter_map_array : ('a -> 'b option) -> 'a array -> 'b list
26232724(** Extract a sub-list. *)
+1-1
src/tests/fake_system.ml
···475475 record
476476477477 method pop_warnings =
478478- let warnings = record |> U.filter_map (function
478478+ let warnings = record |> List.filter_map (function
479479 | (_ex, Support.Logging.Warning, msg) -> Some msg
480480 | _ -> None) in
481481 record <- [];
+2-2
src/tests/test_feed.ml
···3030 let feed = F.parse system root (Some local_path) in
31313232 let () =
3333- let langs = Support.Locale.score_langs @@ U.filter_map Support.Locale.parse_lang ["en_US"; "en_GB"; "fr"] in
3333+ let langs = Support.Locale.score_langs @@ List.filter_map Support.Locale.parse_lang ["en_US"; "en_GB"; "fr"] in
3434 assert_equal 6 (Support.Locale.score_lang langs @@ Some "en_US");
3535 assert_equal 4 (Support.Locale.score_lang langs @@ Some "en_GB");
3636 assert_equal 3 (Support.Locale.score_lang langs @@ Some "en");
···3939 assert_equal 3 (Support.Locale.score_lang langs @@ None) in
40404141 let test ?description expected langs =
4242- let langs = Support.Locale.score_langs @@ U.filter_map Support.Locale.parse_lang langs in
4242+ let langs = Support.Locale.score_langs @@ List.filter_map Support.Locale.parse_lang langs in
4343 Fake_system.assert_str_equal expected @@ Fake_system.expect @@ F.get_summary langs feed;
4444 description |> if_some (fun d ->
4545 Fake_system.assert_str_equal d @@ Fake_system.expect @@ F.get_description langs feed
···158158 attrs := !attrs |> Q.AttrMap.add_no_ns IfaceConfigAttr.stability_policy (Stability.to_string policy)
159159 );
160160161161- let child_nodes = iface_config.extra_feeds |> U.filter_map add_import_elem in
161161+ let child_nodes = iface_config.extra_feeds |> List.filter_map add_import_elem in
162162 let root = ZI.make ~attrs:!attrs ~child_nodes "interface-preferences" in
163163164164 config_file |> config.system#atomic_write [Open_wronly; Open_binary] ~mode:0o644 (fun ch ->
+2-2
src/zeroinstall/fetch.ml
···151151152152 (* Start a download for each missing key *)
153153 let missing_keys =
154154- sigs |> U.filter_map (function
154154+ sigs |> List.filter_map (function
155155 | G.ErrSig (G.UnknownKey key) -> Some (fetch key)
156156 | _ -> None
157157 ) in
···243243 trust_db, possibly after confirming with the user. *)
244244 let confirm_keys feed sigs messages =
245245 let `Remote_feed feed_url = feed in
246246- let valid_sigs = sigs |> U.filter_map (function
246246+ let valid_sigs = sigs |> List.filter_map (function
247247 | G.ValidSig info -> Some info
248248 | G.BadSig _ | G.ErrSig _ -> None
249249 ) in
+1-1
src/zeroinstall/gui.ml
···431431 | Some description -> Str.split (Str.regexp_string "\n\n") description |> List.map format_para
432432 | None -> ["-"] in
433433434434- let homepages = Feed.root feed |> Element.feed_metadata |> U.filter_map (function
434434+ let homepages = Feed.root feed |> Element.feed_metadata |> List.filter_map (function
435435 | `Homepage homepage -> Some (Element.simple_content homepage)
436436 | _ -> None
437437 ) in
+3-3
src/zeroinstall/host_python.ml
···7575let make system =
7676 let (_host_os, host_machine) = Arch.platform system in
7777 let python_installations = lazy (
7878- ["python"; "python2"; "python3"] |> Utils.filter_map (fun name ->
7878+ ["python"; "python2"; "python3"] |> List.filter_map (fun name ->
7979 Utils.find_in_path system name |> pipe_some (fun path ->
8080 try
8181 let json = [path; "-c"; python_test_code] |> Utils.check_output system Yojson.Basic.from_channel in
···134134 (id, make_host_impl t ~package:"host-python" path version ~commands url id)
135135 )
136136 | `Remote_feed "http://repo.roscidus.com/python/python-gobject" as url ->
137137- Lazy.force t.python_installations |> Utils.filter_map (fun installation ->
137137+ Lazy.force t.python_installations |> List.filter_map (fun installation ->
138138 match installation.python_gobject with
139139 | Some info ->
140140 let id = "package:host:python-gobject:" ^ info.version in
···143143 | None -> None
144144 )
145145 | `Remote_feed "https://apps.0install.net/python/pygobject.xml" as url ->
146146- Lazy.force t.python_installations |> Utils.filter_map (fun installation ->
146146+ Lazy.force t.python_installations |> List.filter_map (fun installation ->
147147 match installation.python_gobject with
148148 | Some info ->
149149 let id = "package:host:python-gobject:" ^ info.version in
+1-1
src/zeroinstall/impl.ml
···270270 match AttrMap.get_no_ns "langs" impl.props.attrs with
271271 | Some langs -> Str.split XString.re_space langs
272272 | None -> ["en"] in
273273- Support.Utils.filter_map Support.Locale.parse_lang langs
273273+ List.filter_map Support.Locale.parse_lang langs
274274275275let is_retrievable_without_network cache_impl =
276276 let ok_without_network elem =
+3-3
src/zeroinstall/impl_provider.ml
···272272 in
273273274274 let get_extra_feeds ~problem want_source iface_config =
275275- Support.Utils.filter_map (get_feed_if_useful ~problem want_source) iface_config.Feed_cache.extra_feeds in
275275+ List.filter_map (get_feed_if_useful ~problem want_source) iface_config.Feed_cache.extra_feeds in
276276277277 let impls_for_iface = U.memoize ~initial_size:10 (fun (iface, want_source) ->
278278 let master_feed = feed_provider#get_feed (Feed_url.master_feed_of_iface iface) in
···288288 problem (Printf.sprintf "Main feed '%s' not available" iface);
289289 ([], None)
290290 | Some ((feed, _overrides) as pair) ->
291291- let sub_feeds = U.filter_map (get_feed_if_useful ~problem want_source) (Feed.imported_feeds feed) in
291291+ let sub_feeds = List.filter_map (get_feed_if_useful ~problem want_source) (Feed.imported_feeds feed) in
292292 let impls = List.concat (List.map (get_impls ~problem) (pair :: sub_feeds)) in
293293 (impls, iface_config.Feed_cache.stability_policy) in
294294···321321 if scope_filter.Scope_filter.may_compile && not want_source then (
322322 let (host_os, host_machine) = Arch.platform config.system in
323323 let host_arch = (Some host_os, Some host_machine) in
324324- U.filter_map (src_to_bin ~host_arch ~rejects) existing_impls
324324+ List.filter_map (src_to_bin ~host_arch ~rejects) existing_impls
325325 ) else (
326326 (existing_impls :> Impl.generic_implementation list)
327327 ) in
+1-1
src/zeroinstall/packagekit.ml
···189189 | None ->
190190 log_info "No size returned for '%s'" packagekit_id;
191191 Some impl in
192192- let results = U.filter_map add_size impls in
192192+ let results = List.filter_map add_size impls in
193193 Lwt.wakeup resolver {
194194 results;
195195 problems = !problems;
+3-3
src/zeroinstall/selections.ml
···184184(** Collect all the commands needed by this dependency. *)
185185let get_required_commands dep =
186186 let commands =
187187- Element.bindings dep |> U.filter_map (fun node ->
187187+ Element.bindings dep |> List.filter_map (fun node ->
188188 Binding.parse_binding node |> Binding.get_command
189189 ) in
190190 match Element.classify_dep dep with
···193193194194let make_deps children =
195195 let self_commands = ref [] in
196196- let deps = children |> U.filter_map (function
196196+ let deps = children |> List.filter_map (function
197197 | `Requires r -> Some (r :> dependency)
198198 | `Runner r -> Some (r :> dependency)
199199 | #Element.binding as b ->
···216216let get_command sel name = Element.get_command name sel
217217218218let selected_commands sel =
219219- Element.deps_and_bindings sel |> U.filter_map (function
219219+ Element.deps_and_bindings sel |> List.filter_map (function
220220 | `Command c -> Some (Element.command_name c)
221221 | _ -> None
222222 )
+2-2
src/zeroinstall/solver.ml
···9393 let make_deps role zi_deps self_bindings =
9494 let impl_provider = role.scope in
9595 let deps = zi_deps
9696- |> U.filter_map (fun zi_dep ->
9696+ |> List.filter_map (fun zi_dep ->
9797 if impl_provider#is_dep_needed zi_dep then Some (role, zi_dep)
9898 else None
9999 ) in
100100 let self_commands = self_bindings
101101- |> U.filter_map (fun binding ->
101101+ |> List.filter_map (fun binding ->
102102 Element.classify_binding binding |> Binding.parse_binding |> Binding.get_command
103103 ) in
104104 (deps, self_commands)
+1-1
src/zeroinstall/tree.ml
···4747 );
48484949 let children =
5050- !deps |> U.filter_map (fun dep ->
5050+ !deps |> List.filter_map (fun dep ->
5151 let {Model.dep_role; dep_importance; dep_required_commands = _} = Model.dep_info dep in
5252 if dep_importance <> `Restricts then
5353 build_node dep_role ~essential:(dep_importance = `Essential)