-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathdeferred_result.ml
123 lines (102 loc) · 2.83 KB
/
deferred_result.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
open Core
open Deferred_std
module Deferred = Deferred1
module T = struct
type ('a, 'error) t = ('a, 'error) Result.t Deferred.t
end
include T
let combine t1 t2 ~ok ~err =
let%map t1 and t2 in
Result.combine t1 t2 ~ok ~err
;;
include Monad.Make2 (struct
include T
let return a = Deferred.return (Ok a)
let bind t ~f =
Deferred.bind t ~f:(function
| Ok a -> f a
| Error _ as error -> Deferred.return error)
;;
let map t ~f = Deferred.map t ~f:(fun r -> Result.map r ~f)
let map = `Custom map
end)
let fail x = Deferred.return (Error x)
let failf format = Printf.ksprintf fail format
let map_error t ~f = Deferred.map t ~f:(fun r -> Result.map_error r ~f)
module List = struct
open Let_syntax
let foldi list ~init:acc ~f =
let rec loop i acc = function
| [] -> return acc
| hd :: tl ->
let%bind acc = f i acc hd in
loop (i + 1) acc tl
in
loop 0 acc list
;;
let fold t ~init ~f = foldi t ~init ~f:(fun _ a x -> f a x)
let seqmapi t ~f =
foldi t ~init:[] ~f:(fun i bs a ->
let%map b = f i a in
b :: bs)
>>| List.rev
;;
let iteri t ~f = foldi t ~init:() ~f:(fun i () x -> f i x)
let mapi t ~f = seqmapi t ~f
let filter_mapi t ~f = mapi t ~f >>| List.filter_opt
let concat_mapi t ~f = mapi t ~f >>| List.concat
let filteri t ~f =
filter_mapi t ~f:(fun i x ->
let%map b = f i x in
if b then Some x else None)
;;
let find_mapi t ~f =
let rec find_mapi t ~f i =
match t with
| [] -> return None
| hd :: tl ->
(match%bind f i hd with
| None -> find_mapi tl ~f (i + 1)
| Some _ as some -> return some)
in
find_mapi t ~f 0
;;
let find_map t ~f = find_mapi t ~f:(fun _ a -> f a)
let findi t ~f =
find_mapi t ~f:(fun i elt ->
let%map b = f i elt in
if b then Some (i, elt) else None)
;;
let find t ~f =
find_map t ~f:(fun elt ->
let%map b = f elt in
if b then Some elt else None)
;;
let existsi t ~f =
match%map
find_mapi t ~f:(fun i elt ->
let%map b = f i elt in
if b then Some () else None)
with
| Some () -> true
| None -> false
;;
let for_alli t ~f =
match%map
find_mapi t ~f:(fun i elt ->
let%map b = f i elt in
if not b then Some () else None)
with
| Some () -> false
| None -> true
;;
let iter t ~f = iteri t ~f:(fun _ a -> f a)
let map t ~f = mapi t ~f:(fun _ a -> f a)
let filter t ~f = filteri t ~f:(fun _ a -> f a)
let filter_map t ~f = filter_mapi t ~f:(fun _ a -> f a)
let concat_map t ~f = concat_mapi t ~f:(fun _ a -> f a)
let find_map t ~f = find_mapi t ~f:(fun _ a -> f a)
let exists t ~f = existsi t ~f:(fun _ a -> f a)
let for_all t ~f = for_alli t ~f:(fun _ a -> f a)
let init n ~f = map (List.init n ~f:Fn.id) ~f
end