Source file deferred_option.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
open Core
module Deferred = Deferred1

module T = struct
  type 'a t = 'a Option.t Deferred.t
end

include T

include Monad.Make (struct
    include T

    let return a = Deferred.return (Some a)

    let bind t ~f =
      Deferred.bind t ~f:(function
        | Some a -> f a
        | None -> Deferred.return None)
    ;;

    let map t ~f = Deferred.map t ~f:(fun r -> Option.map r ~f)
    let map = `Custom map
  end)

module Container = struct
  (* Every function below is some instance of deferred [Option.value_map]. *)

  let value_map option ~default ~f =
    match option with
    | None -> Deferred.return default
    | Some value -> f value
  ;;

  let fold option ~init ~f = value_map option ~default:init ~f:(fun value -> f init value)
  let exists option ~f = value_map option ~default:false ~f
  let for_all option ~f = value_map option ~default:true ~f
  let iter option ~f = value_map option ~default:() ~f

  let map option ~f =
    value_map option ~default:None ~f:(fun value ->
      Deferred.map ~f:Option.return (f value))
  ;;

  let all option =
    value_map option ~default:None ~f:(fun deferred ->
      Deferred.map ~f:Option.return deferred)
  ;;

  let all_unit option = value_map option ~default:() ~f:Fn.id

  (* Several exported functions are equivalent to a deferred [Option.bind]. *)

  let bind option ~f = value_map option ~default:None ~f
  let concat_map = bind
  let filter_map = bind
  let find_map = bind

  (* [find] and [filter] are equivalent. *)

  let find option ~f =
    value_map option ~default:None ~f:(fun value ->
      Deferred.map (f value) ~f:(function
        | false -> None
        | true -> Some value))
  ;;

  let filter = find
end