diff options
author | Louis Pilfold <louis@lpil.uk> | 2021-07-18 21:48:58 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-07-18 21:48:58 +0100 |
commit | eb2f87a814ba3235a4e98c201e8e82e25da2e9d0 (patch) | |
tree | 2f89bd4fc9954078e887c3fdef272b98d225a04f | |
parent | 3d287285eb8a1e824a400d01afa543454eff7b44 (diff) | |
download | gleam_stdlib-eb2f87a814ba3235a4e98c201e8e82e25da2e9d0.tar.gz gleam_stdlib-eb2f87a814ba3235a4e98c201e8e82e25da2e9d0.zip |
Remove function.rescue function
Closes https://github.com/gleam-lang/gleam/issues/1196
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/gleam/function.gleam | 108 | ||||
-rw-r--r-- | test/gleam/function_test.gleam | 197 |
3 files changed, 135 insertions, 172 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index d84fb76..760ea9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## Unreleased - The `os` module has been moved to the `gleam_os` library. +- The `rescue` function has been removed from the `function` library in favour + of target specific versions in Erlang and JavaScript specific libraries. - The `bool`, `list`, `order`, and `pair` modules now support JavaScript compilation. - The `map.update` function now uses `Option` rather than `Result`. diff --git a/src/gleam/function.gleam b/src/gleam/function.gleam index 937a9bc..8010639 100644 --- a/src/gleam/function.gleam +++ b/src/gleam/function.gleam @@ -1,73 +1,53 @@ -if erlang { - import gleam/dynamic.{Dynamic} - - /// Takes two functions and chains them together to form one function that takes - /// the input from the first and returns the output of the second. - /// - pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { - fn(a) { fun2(fun1(a)) } - } - - /// Takes a function with arity two - /// and returns a curried equivalent. - /// fn(a, b) -> c becomes fn(a) -> fn(b) -> c - pub fn curry2(fun: fn(a, b) -> value) { - fn(a) { fn(b) { fun(a, b) } } - } - - /// Takes a function with arity three - /// and returns a curried equivalent. - /// fn(a, b, c) -> d becomes fn(a) -> fn(b) -> fn(c) -> d - pub fn curry3(fun: fn(a, b, c) -> value) { - fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } - } +/// Takes two functions and chains them together to form one function that takes +/// the input from the first and returns the output of the second. +/// +pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { + fn(a) { fun2(fun1(a)) } +} - /// Takes a function with arity four - /// and returns a curried equivalent. - pub fn curry4(fun: fn(a, b, c, d) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } - } +/// Takes a function with arity two +/// and returns a curried equivalent. +/// fn(a, b) -> c becomes fn(a) -> fn(b) -> c +pub fn curry2(fun: fn(a, b) -> value) { + fn(a) { fn(b) { fun(a, b) } } +} - /// Takes a function with arity five - /// and returns a curried equivalent. - pub fn curry5(fun: fn(a, b, c, d, e) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } - } +/// Takes a function with arity three +/// and returns a curried equivalent. +/// fn(a, b, c) -> d becomes fn(a) -> fn(b) -> fn(c) -> d +pub fn curry3(fun: fn(a, b, c) -> value) { + fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } +} - /// Takes a function with arity six - /// and returns a curried equivalent. - pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { - fn(a) { - fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } - } - } +/// Takes a function with arity four +/// and returns a curried equivalent. +pub fn curry4(fun: fn(a, b, c, d) -> value) { + fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } +} - /// Takes a function that takes two arguments and returns a new function that - /// takes the same two arguments, but in reverse order. - /// - pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { - fn(b, a) { fun(a, b) } - } +/// Takes a function with arity five +/// and returns a curried equivalent. +pub fn curry5(fun: fn(a, b, c, d, e) -> value) { + fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } +} - /// A function that always returns its input value. - /// - pub fn identity(x: a) -> a { - x +/// Takes a function with arity six +/// and returns a curried equivalent. +pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { + fn(a) { + fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } } +} - pub type Exception { - Exited(Dynamic) - Thrown(Dynamic) - Errored(Dynamic) - } +/// Takes a function that takes two arguments and returns a new function that +/// takes the same two arguments, but in reverse order. +/// +pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { + fn(b, a) { fun(a, b) } +} - /// Gleam doesn't offer any way to raise exceptions, but they may still occur - /// due to bugs when working with unsafe code, such as when calling Erlang - /// function. - /// - /// This function will catch any error thrown and convert it into a result - /// rather than crashing the process. - /// - pub external fn rescue(fn() -> a) -> Result(a, Exception) = - "gleam_stdlib" "rescue" +/// A function that always returns its input value. +/// +pub fn identity(x: a) -> a { + x } diff --git a/test/gleam/function_test.gleam b/test/gleam/function_test.gleam index ec65f63..0b3bd8c 100644 --- a/test/gleam/function_test.gleam +++ b/test/gleam/function_test.gleam @@ -1,128 +1,109 @@ -if erlang { - import gleam/should - import gleam/dynamic - import gleam/function - import gleam/int - import gleam/list - import gleam/result - import gleam/string - - pub fn compose_test() { - let add_two = fn(int: Int) { int + 2 } - let add_three = fn(int: Int) { int + 3 } - - let add_five = function.compose(add_two, add_three) - - 1 - |> add_five - |> should.equal(6) - - // Takes a list of ints and returns the head as a string (if there is one, or - // else "0" if there is not) - let head_to_string = - list.head - |> function.compose(result.unwrap(_, 0)) - |> function.compose(int.to_string) - - [1] - |> head_to_string - |> should.equal("1") - - [] - |> head_to_string - |> should.equal("0") - } - - pub fn curry2_test() { - let fun = fn(a, b) { a + b } - let curried = function.curry2(fun) - - curried(1)(2) - |> should.equal(3) - } - - pub fn curry3_test() { - let fun = fn(a, b, c) { a + b + c } - let curried = function.curry3(fun) +import gleam/should +import gleam/dynamic +import gleam/function +import gleam/int +import gleam/list +import gleam/result +import gleam/string + +pub fn compose_test() { + let add_two = fn(int: Int) { int + 2 } + let add_three = fn(int: Int) { int + 3 } + + let add_five = function.compose(add_two, add_three) + + 1 + |> add_five + |> should.equal(6) + + // Takes a list of ints and returns the head as a string (if there is one, or + // else "0" if there is not) + let head_to_string = + list.head + |> function.compose(result.unwrap(_, 0)) + |> function.compose(int.to_string) + + [1] + |> head_to_string + |> should.equal("1") + + [] + |> head_to_string + |> should.equal("0") +} - curried(1)(2)(4) - |> should.equal(7) - } +pub fn curry2_test() { + let fun = fn(a, b) { a + b } + let curried = function.curry2(fun) - pub fn curry4_test() { - let fun = fn(a, b, c, d) { a + b + c + d } - let curried = function.curry4(fun) + curried(1)(2) + |> should.equal(3) +} - curried(1)(2)(4)(8) - |> should.equal(15) - } +pub fn curry3_test() { + let fun = fn(a, b, c) { a + b + c } + let curried = function.curry3(fun) - pub fn curry5_test() { - let fun = fn(a, b, c, d, e) { a + b + c + d + e } - let curried = function.curry5(fun) + curried(1)(2)(4) + |> should.equal(7) +} - curried(1)(2)(4)(8)(16) - |> should.equal(31) - } +pub fn curry4_test() { + let fun = fn(a, b, c, d) { a + b + c + d } + let curried = function.curry4(fun) - pub fn curry6_test() { - let fun = fn(a, b, c, d, e, f) { a + b + c + d + e + f } - let curried = function.curry6(fun) + curried(1)(2)(4)(8) + |> should.equal(15) +} - curried(1)(2)(4)(8)(16)(32) - |> should.equal(63) - } +pub fn curry5_test() { + let fun = fn(a, b, c, d, e) { a + b + c + d + e } + let curried = function.curry5(fun) - pub fn flip_test() { - let fun = fn(s: String, i: Int) { - s - |> string.append("String: '", _) - |> string.append("', Int: '") - |> string.append(int.to_string(i)) - |> string.append("'") - } + curried(1)(2)(4)(8)(16) + |> should.equal(31) +} - let flipped_fun = function.flip(fun) +pub fn curry6_test() { + let fun = fn(a, b, c, d, e, f) { a + b + c + d + e + f } + let curried = function.curry6(fun) - fun("Bob", 1) - |> should.equal("String: 'Bob', Int: '1'") + curried(1)(2)(4)(8)(16)(32) + |> should.equal(63) +} - flipped_fun(2, "Alice") - |> should.equal("String: 'Alice', Int: '2'") +pub fn flip_test() { + let fun = fn(s: String, i: Int) { + s + |> string.append("String: '", _) + |> string.append("', Int: '") + |> string.append(int.to_string(i)) + |> string.append("'") } - pub fn identity_test() { - 1 - |> function.identity - |> should.equal(1) + let flipped_fun = function.flip(fun) - "" - |> function.identity - |> should.equal("") + fun("Bob", 1) + |> should.equal("String: 'Bob', Int: '1'") - [] - |> function.identity - |> should.equal([]) - - #(1, 2.0) - |> function.identity - |> should.equal(#(1, 2.0)) - } - - external fn throw(a) -> Nil = - "erlang" "throw" + flipped_fun(2, "Alice") + |> should.equal("String: 'Alice', Int: '2'") +} - external fn raise_error(a) -> Nil = - "erlang" "error" +pub fn identity_test() { + 1 + |> function.identity + |> should.equal(1) - pub fn rescue_test() { - function.rescue(fn() { 1 }) - |> should.equal(Ok(1)) + "" + |> function.identity + |> should.equal("") - function.rescue(fn() { throw(1) }) - |> should.equal(Error(function.Thrown(dynamic.from(1)))) + [] + |> function.identity + |> should.equal([]) - function.rescue(fn() { raise_error("") }) - |> should.equal(Error(function.Errored(dynamic.from("")))) - } + #(1, 2.0) + |> function.identity + |> should.equal(#(1, 2.0)) } |