Skip to content

Commit 1284c50

Browse files
committed
Add Belt.Either
1 parent 03b944d commit 1284c50

File tree

3 files changed

+136
-3
lines changed

3 files changed

+136
-3
lines changed

jscomp/others/belt.ml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,12 @@ module HashSet = Belt_HashSet
232232
*)
233233
module HashMap = Belt_HashMap
234234

235+
(** {!Belt.HashMap}
236+
237+
The top level provides generic {b mutable} hash map operations.
238+
239+
It also has two specialized inner modules
240+
{!Belt.HashMap.Int} and {!Belt.HashMap.String}
241+
*)
235242

236-
237-
238-
243+
module Either = Belt_Either

jscomp/others/belt_Either.ml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
(* https://gist.github.com/NicolasT/65dad40b203da7c65b4c *)
2+
3+
type ('a, 'b) t = Left of 'a | Right of 'b
4+
5+
(** Constructor functions *)
6+
let left a = Left a
7+
let right b = Right b
8+
9+
let either l r = function
10+
| Left v -> l v
11+
| Right v -> r v
12+
13+
(** Bifunctor interface *)
14+
let bimap l r = either (fun v -> left (l v)) (fun v -> right (r v))
15+
16+
external id : 'a -> 'a = "%identity"
17+
let const v = fun _ -> v
18+
19+
(** Functor interface *)
20+
let map f = bimap id f
21+
let (<$>) = map
22+
let map_left f = bimap f id
23+
24+
(** Monadic interface *)
25+
let bind m k = either left k m
26+
27+
let return = right
28+
let (>>=) = bind
29+
let throw = left
30+
31+
(** Applicative interface *)
32+
let pure = return
33+
let apply f v = f >>= fun f' -> v >>= fun v' -> pure (f' v')
34+
let (<*>) = apply
35+
36+
(** Turn a function result in a value or an error *)
37+
let try_ f = try pure (f ()) with exn -> throw exn
38+
39+
(** Predicates *)
40+
let is_left v = either (const true) (const false) v
41+
let is_right v = either (const false) (const true) v
42+
43+
let to_string l r = either
44+
(fun v -> "Left (" ^ (l v) ^ ")")
45+
(fun v -> "Right (" ^ (r v) ^ ")")
46+
47+
(** Extract a value of raise an exception *)
48+
let error v = either (fun e -> raise e) id v
49+
50+
(** Silence into an option *)
51+
let hush v = either (const None) (fun v' -> Some v') v
52+
53+
(** Expand from an option *)
54+
let note e = function
55+
| None -> Left e
56+
| Some v -> Right v
57+
58+
let fold f z = either (const z) (fun v -> f v z)
59+
60+
let lefts xs =
61+
List.fold_left(fun acc x ->
62+
match x with
63+
| Left l -> List.append acc [l]
64+
| Right r -> acc
65+
) [] xs
66+
67+
let rights xs =
68+
List.fold_left(fun acc x ->
69+
match x with
70+
| Left l -> acc
71+
| Right r -> List.append acc [r]
72+
) [] xs
73+
74+
let array_lefts xs =
75+
Array.fold_left(fun acc x ->
76+
match x with
77+
| Left l -> Array.append acc [|l|]
78+
| Right r -> acc
79+
) [||] xs
80+
81+
let array_rights xs =
82+
Array.fold_left(fun acc x ->
83+
match x with
84+
| Left l -> acc
85+
| Right r -> Array.append acc [|r|]
86+
) [||] xs
87+

jscomp/others/belt_Either.mli

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
type ('a, 'b) t = Left of 'a | Right of 'b
2+
3+
val left : 'a -> ('a, 'b) t
4+
val right : 'b -> ('a, 'b) t
5+
6+
val either : ('a -> 'c) -> ('b -> 'c) -> ('a, 'b) t -> 'c
7+
8+
val map : ('b -> 'c) -> ('a, 'b) t -> ('a, 'c) t
9+
val (<$>) : ('b -> 'c) -> ('a, 'b) t -> ('a, 'c) t
10+
val map_left : ('a -> 'c) -> ('a, 'b) t -> ('c, 'b) t
11+
12+
val bimap : ('a -> 'c) -> ('b -> 'd) -> ('a, 'b) t -> ('c, 'd) t
13+
14+
val pure : 'b -> ('a, 'b) t
15+
val apply : ('a, ('b -> 'c)) t -> ('a, 'b) t -> ('a, 'c) t
16+
val (<*>) : ('a, ('b -> 'c)) t -> ('a, 'b) t -> ('a, 'c) t
17+
18+
val return : 'b -> ('a, 'b) t
19+
val bind : ('a, 'b) t -> ('b -> ('a, 'c) t) -> ('a, 'c) t
20+
21+
val (>>=) : ('a, 'b) t -> ('b -> ('a, 'c) t) -> ('a, 'c) t
22+
val throw : 'a -> ('a, 'b) t
23+
24+
val is_left : ('a, 'b) t -> bool
25+
val is_right : ('a, 'b) t -> bool
26+
27+
val to_string : ('a -> string) -> ('b -> string) -> ('a, 'b) t -> string
28+
29+
val error : (exn, 'a) t -> 'a
30+
31+
val try_ : (unit -> 'b) -> (exn, 'b) t
32+
33+
val hush : ('a, 'b) t -> 'b option
34+
val note : 'a -> 'b option -> ('a, 'b) t
35+
36+
val fold : ('b -> 'c -> 'c) -> 'c -> ('a, 'b) t -> 'c
37+
38+
val lefts: (('a, 'b) t) list -> 'a list
39+
val rights: (('a, 'b) t) list -> 'b list
40+
val array_lefts: (('a, 'b) t) array -> 'a array
41+
val array_rights: (('a, 'b) t) array -> 'b array

0 commit comments

Comments
 (0)