Skip to content

Commit

Permalink
Merge pull request #53 from andywhite37/option-lazy
Browse files Browse the repository at this point in the history
Change Option fold/foldStrict to foldLazy/fold (and same for getOrElse)
  • Loading branch information
andywhite37 authored Apr 11, 2019
2 parents ab1ba7c + 7e3b269 commit 488bfd4
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 21 deletions.
24 changes: 20 additions & 4 deletions __tests__/Relude_Option_test.re
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,36 @@ module Int = Relude_Int;
module Option = Relude_Option;

describe("Option", () => {
test("foldLazy maps value when option is Some", () =>
expect(Option.foldLazy(_ => "", string_of_int, Some(1))) |> toEqual("1")
);

test("foldLazy uses default when option is None", () =>
expect(Option.foldLazy(_ => "", string_of_int, None)) |> toEqual("")
);

test("fold maps value when option is Some", () =>
expect(Option.fold(_ => "", string_of_int, Some(1))) |> toEqual("1")
expect(Option.fold("", string_of_int, Some(1))) |> toEqual("1")
);

test("fold uses default when option is None", () =>
expect(Option.fold(_ => "", string_of_int, None)) |> toEqual("")
expect(Option.fold("", string_of_int, None)) |> toEqual("")
);

test("getOrElseLazy extracts value when option is Some", () =>
expect(Option.getOrElseLazy(_ => 0, Some(1))) |> toEqual(1)
);

test("getOrElseLazy uses default when option is None", () =>
expect(Option.getOrElseLazy(_ => 0, None)) |> toEqual(0)
);

test("getOrElse extracts value when option is Some", () =>
expect(Option.getOrElse(_ => 0, Some(1))) |> toEqual(1)
expect(Option.getOrElse(0, Some(1))) |> toEqual(1)
);

test("getOrElse uses default when option is None", () =>
expect(Option.getOrElse(_ => 0, None)) |> toEqual(0)
expect(Option.getOrElse(0, None)) |> toEqual(0)
);

test("toList has one item when option is Some", () =>
Expand Down
4 changes: 2 additions & 2 deletions __tests__/testUtils/FS.re
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ module IO = {
"Read failed: "
++ (
Js.Exn.message(err')
|> Relude_Option.getOrElse(_ => "No error")
|> Relude_Option.getOrElseLazy(_ => "No error")
),
);
onDone(Error(err'));
Expand All @@ -81,7 +81,7 @@ module IO = {
"Write failed: "
++ (
Js.Exn.message(err')
|> Relude_Option.getOrElse(_ => "No error")
|> Relude_Option.getOrElseLazy(_ => "No error")
),
);
onDone(Error(err'));
Expand Down
2 changes: 1 addition & 1 deletion src/Relude_IO.re
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ let async: 'a 'e. ((Result.t('a, 'e) => unit) => unit) => t('a, 'e) =

let fromOption: 'a 'e. (unit => 'e, option('a)) => t('a, 'e) =
(getError, option) =>
option |> Option.fold(() => throw(getError()), pure);
option |> Option.foldLazy(() => throw(getError()), pure);

let fromResult: 'a 'e. Result.t('a, 'e) => t('a, 'e) =
res => res |> Result.fold(throw, pure);
Expand Down
6 changes: 3 additions & 3 deletions src/Relude_List.re
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ let tail: list('a) => option(list('a)) =
| [_, ...xs] => Some(xs);

let tailOrEmpty: list('a) => list('a) =
xs => tail(xs) |> Relude_Option.getOrElseStrict([]);
xs => tail(xs) |> Relude_Option.getOrElse([]);

let rec init: list('a) => option(list('a)) =
fun
| [] => None
| [_] => Some([])
| [x, ...xs] =>
Some(cons(x, Relude_Option.getOrElseStrict([], init(xs))));
Some(cons(x, Relude_Option.getOrElse([], init(xs))));

let rec last: list('a) => option('a) =
fun
Expand Down Expand Up @@ -154,7 +154,7 @@ let mapOption: ('a => option('b), list('a)) => list('b) =
(f, xs) =>
foldLeft(
(acc, curr) =>
Relude_Option.fold(() => acc, v => [v, ...acc], f(curr)),
Relude_Option.fold(acc, v => [v, ...acc], f(curr)),
[],
xs,
)
Expand Down
22 changes: 11 additions & 11 deletions src/Relude_Option.re
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
let fold: (unit => 'b, 'a => 'b, option('a)) => 'b =
let foldLazy: (unit => 'b, 'a => 'b, option('a)) => 'b =
(default, f, opt) =>
switch (opt) {
| Some(v) => f(v)
| None => default()
};

let foldStrict: ('b, 'a => 'b, option('a)) => 'b =
let fold: ('b, 'a => 'b, option('a)) => 'b =
(default, f, opt) =>
switch (opt) {
| Some(v) => f(v)
| None => default
};

let forEach: 'a. ('a => unit, option('a)) => unit =
(f, opt) => foldStrict((), f, opt);
(f, opt) => fold((), f, opt);

let getOrElse: (unit => 'a, option('a)) => 'a =
default => fold(default, a => a);
let getOrElseLazy: (unit => 'a, option('a)) => 'a =
default => foldLazy(default, a => a);

let getOrElseStrict: ('a, option('a)) => 'a =
default => foldStrict(default, a => a);
let getOrElse: ('a, option('a)) => 'a =
default => fold(default, a => a);

let toList: option('a) => list('a) = t => fold(_ => [], v => [v], t);
let toList: option('a) => list('a) = t => fold([], v => [v], t);

let toArray: option('a) => array('a) = t => fold(_ => [||], v => [|v|], t);
let toArray: option('a) => array('a) = t => fold([||], v => [|v|], t);

let isSome: option('a) => bool = t => fold(_ => false, _ => true, t);
let isSome: option('a) => bool = t => fold(false, _ => true, t);

let isNone: option('a) => bool = t => fold(_ => true, _ => false, t);
let isNone: option('a) => bool = t => fold(true, _ => false, t);

let map: ('a => 'b, option('a)) => option('b) =
(fn, opt) => BsAbstract.Option.Functor.map(fn, opt);
Expand Down

0 comments on commit 488bfd4

Please sign in to comment.