package stdune
Source file monad.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 124 125 126 127 128 129 130 131 132module type Basic = Monad_intf.Basic module type S = Monad_intf.S module type List = Monad_intf.List module type Option = Monad_intf.Option module type Result = Monad_intf.Result module Make (M : Basic) = struct include M let map t ~f = bind t ~f:(fun x -> return (f x)) module O = struct let ( >>= ) t f = bind t ~f let ( >>| ) t f = map t ~f let ( >>> ) a b = bind a ~f:(fun () -> b) let ( let+ ) t f = map t ~f let ( and+ ) x y = let open M in x >>= fun x -> y >>= fun y -> return (x, y) let ( let* ) t f = bind t ~f let ( and* ) = ( and+ ) end end [@@inlined always] module Id = Make (struct type 'a t = 'a let return x = x let bind x ~f = f x end) module List (M : S) = struct open M open M.O let rec find_map xs ~f = match xs with | [] -> return None | x :: xs -> ( let* x = f x in match x with | None -> find_map xs ~f | Some s -> return (Some s)) let rec fold_left xs ~f ~init = match xs with | [] -> return init | x :: xs -> let* init = f init x in fold_left xs ~f ~init let filter_map xs ~f = let rec loop acc = function | [] -> return (List.rev acc) | x :: xs -> ( let* y = f x in match y with | None -> loop acc xs | Some y -> loop (y :: acc) xs) in loop [] xs let filter xs ~f = filter_map xs ~f:(fun x -> let+ pred = f x in Option.some_if pred x) let map xs ~f = filter_map xs ~f:(fun x -> let+ x = f x in Some x) let concat_map xs ~f = map xs ~f >>| List.concat let rec iter xs ~f = match xs with | [] -> return () | x :: xs -> let* () = f x in iter xs ~f let rec for_all xs ~f = match xs with | [] -> return true | x :: xs -> let* pred = f x in if pred then for_all xs ~f else return false let rec exists xs ~f = match xs with | [] -> return false | x :: xs -> let* pred = f x in if pred then return true else exists xs ~f end module Option (M : S) = struct let iter option ~f = match option with | None -> M.return () | Some a -> f a let map option ~f = match option with | None -> M.return None | Some a -> M.map (f a) ~f:Option.some let bind option ~f = match option with | None -> M.return None | Some a -> f a end module Result (M : S) = struct let iter result ~f = match result with | Error _ -> M.return () | Ok a -> f a end