diff --git a/src/gleam_community/maths/arithmetics.gleam b/src/gleam_community/maths/arithmetics.gleam index ee27306..b44f80a 100644 --- a/src/gleam_community/maths/arithmetics.gleam +++ b/src/gleam_community/maths/arithmetics.gleam @@ -442,7 +442,7 @@ pub fn int_sum(arr: List(Int)) -> Int { pub fn float_product( arr: List(Float), weights: option.Option(List(Float)), -) -> Result(Float, String) { +) -> Result(Float, Nil) { case arr, weights { [], _ -> 1.0 @@ -452,22 +452,16 @@ pub fn float_product( |> list.fold(1.0, fn(acc, a) { a *. acc }) |> Ok _, option.Some(warr) -> { - let results = - list.zip(arr, warr) - |> list.map(fn(a) { - pair.first(a) - |> elementary.power(pair.second(a)) - }) - |> result.all - case results { - Ok(prods) -> - prods - |> list.fold(1.0, fn(acc, a) { a *. acc }) - |> Ok - Error(msg) -> - msg - |> Error - } + list.zip(arr, warr) + |> list.map(fn(a: #(Float, Float)) -> Result(Float, Nil) { + pair.first(a) + |> elementary.power(pair.second(a)) + }) + |> result.all + |> result.map(fn(prods) { + prods + |> list.fold(1.0, fn(acc: Float, a: Float) -> Float { a *. acc }) + }) } } } diff --git a/src/gleam_community/maths/combinatorics.gleam b/src/gleam_community/maths/combinatorics.gleam index 726ae52..a3a4e7e 100644 --- a/src/gleam_community/maths/combinatorics.gleam +++ b/src/gleam_community/maths/combinatorics.gleam @@ -130,12 +130,10 @@ pub fn combination( n: Int, k: Int, mode: option.Option(CombinatoricsMode), -) -> Result(Int, String) { +) -> Result(Int, Nil) { case n, k { - _, _ if n < 0 -> - "Invalid input argument: n < 0. Valid input is n >= 0." |> Error - _, _ if k < 0 -> - "Invalid input argument: k < 0. Valid input is k >= 0." |> Error + _, _ if n < 0 -> Error(Nil) + _, _ if k < 0 -> Error(Nil) _, _ -> { case mode { option.Some(WithRepetitions) -> combination_with_repetitions(n, k) @@ -145,12 +143,11 @@ pub fn combination( } } -fn combination_with_repetitions(n: Int, k: Int) -> Result(Int, String) { - { n + k - 1 } - |> combination_without_repetitions(k) +fn combination_with_repetitions(n: Int, k: Int) -> Result(Int, Nil) { + combination_without_repetitions(n + k - 1, k) } -fn combination_without_repetitions(n: Int, k: Int) -> Result(Int, String) { +fn combination_without_repetitions(n: Int, k: Int) -> Result(Int, Nil) { case n, k { _, _ if k == 0 || k == n -> { 1 |> Ok @@ -202,17 +199,11 @@ fn combination_without_repetitions(n: Int, k: Int) -> Result(Int, String) { /// /// /// -pub fn factorial(n) -> Result(Int, String) { +pub fn factorial(n) -> Result(Int, Nil) { case n { - _ if n < 0 -> - "Invalid input argument: n < 0. Valid input is n >= 0." - |> Error - 0 -> - 1 - |> Ok - 1 -> - 1 - |> Ok + _ if n < 0 -> Error(Nil) + 0 -> Ok(1) + 1 -> Ok(1) _ -> list.range(1, n) |> list.fold(1, fn(acc, x) { acc * x }) @@ -300,22 +291,16 @@ pub fn permutation( n: Int, k: Int, mode: option.Option(CombinatoricsMode), -) -> Result(Int, String) { - case n, k { - _, _ if n < 0 -> - "Invalid input argument: n < 0. Valid input is n >= 0." |> Error - _, _ if k < 0 -> - "Invalid input argument: k < 0. Valid input is k >= 0." |> Error - _, _ -> { - case mode { - option.Some(WithRepetitions) -> permutation_with_repetitions(n, k) - _ -> permutation_without_repetitions(n, k) - } - } +) -> Result(Int, Nil) { + case n, k, mode { + _, _, _ if n < 0 -> Error(Nil) + _, _, _ if k < 0 -> Error(Nil) + _, _, option.Some(WithRepetitions) -> permutation_with_repetitions(n, k) + _, _, _ -> permutation_without_repetitions(n, k) } } -fn permutation_without_repetitions(n: Int, k: Int) -> Result(Int, String) { +fn permutation_without_repetitions(n: Int, k: Int) -> Result(Int, Nil) { case n, k { _, _ if k < 0 || k > n -> { 0 |> Ok @@ -330,7 +315,7 @@ fn permutation_without_repetitions(n: Int, k: Int) -> Result(Int, String) { } } -fn permutation_with_repetitions(n: Int, k: Int) -> Result(Int, String) { +fn permutation_with_repetitions(n: Int, k: Int) -> Result(Int, Nil) { let n_float = conversion.int_to_float(n) let k_float = conversion.int_to_float(k) // 'n' ank 'k' are positive integers, so no errors here... @@ -388,29 +373,20 @@ pub fn list_combination( arr: List(a), k: Int, mode: option.Option(CombinatoricsMode), -) -> Result(iterator.Iterator(List(a)), String) { - case k { - _ if k < 0 -> - "Invalid input argument: k < 0. Valid input is k >= 0." - |> Error - _ -> - case mode { - option.Some(WithRepetitions) -> - list_combination_with_repetitions(arr, k) - _ -> list_combination_without_repetitions(arr, k) - } +) -> Result(iterator.Iterator(List(a)), Nil) { + case k, mode { + _, _ if k < 0 -> Error(Nil) + _, option.Some(WithRepetitions) -> list_combination_with_repetitions(arr, k) + _, _ -> list_combination_without_repetitions(arr, k) } } fn list_combination_without_repetitions( arr: List(a), k: Int, -) -> Result(iterator.Iterator(List(a)), String) { +) -> Result(iterator.Iterator(List(a)), Nil) { case k, list.length(arr) { - _, arr_length if k > arr_length -> { - "Invalid input argument: k > length(arr). Valid input is 0 <= k <= length(arr)." - |> Error - } + _, arr_length if k > arr_length -> Error(Nil) // Special case: When k = n, then the entire list is the only valid combination _, arr_length if k == arr_length -> { iterator.single(arr) |> Ok @@ -446,7 +422,7 @@ fn do_list_combination_without_repetitions( fn list_combination_with_repetitions( arr: List(a), k: Int, -) -> Result(iterator.Iterator(List(a)), String) { +) -> Result(iterator.Iterator(List(a)), Nil) { Ok(do_list_combination_with_repetitions(iterator.from_list(arr), k, [])) } @@ -528,17 +504,12 @@ pub fn list_permutation( arr: List(a), k: Int, mode: option.Option(CombinatoricsMode), -) -> Result(iterator.Iterator(List(a)), String) { - case k { - _ if k < 0 -> - "Invalid input argument: k < 0. Valid input is k >= 0." - |> Error - _ -> - case mode { - option.Some(WithRepetitions) -> - list_permutation_with_repetitions(arr, k) - _ -> list_permutation_without_repetitions(arr, k) - } +) -> Result(iterator.Iterator(List(a)), Nil) { + case k, mode { + _, _ if k < 0 -> Error(Nil) + _, option.Some(WithRepetitions) -> + Ok(list_permutation_with_repetitions(arr, k)) + _, _ -> list_permutation_without_repetitions(arr, k) } } @@ -558,12 +529,9 @@ fn remove_first_by_index( fn list_permutation_without_repetitions( arr: List(a), k: Int, -) -> Result(iterator.Iterator(List(a)), String) { +) -> Result(iterator.Iterator(List(a)), Nil) { case k, list.length(arr) { - _, arr_length if k > arr_length -> { - "Invalid input argument: k > length(arr). Valid input is 0 <= k <= length(arr)." - |> Error - } + _, arr_length if k > arr_length -> Error(Nil) _, _ -> { let indexed_arr = list.index_map(arr, fn(x, i) { #(i, x) }) Ok(do_list_permutation_without_repetitions( @@ -594,9 +562,9 @@ fn do_list_permutation_without_repetitions( fn list_permutation_with_repetitions( arr: List(a), k: Int, -) -> Result(iterator.Iterator(List(a)), String) { +) -> iterator.Iterator(List(a)) { let indexed_arr = list.index_map(arr, fn(x, i) { #(i, x) }) - Ok(do_list_permutation_with_repetitions(indexed_arr, k)) + do_list_permutation_with_repetitions(indexed_arr, k) } fn do_list_permutation_with_repetitions( diff --git a/src/gleam_community/maths/elementary.gleam b/src/gleam_community/maths/elementary.gleam index 9c9be4a..491cab7 100644 --- a/src/gleam_community/maths/elementary.gleam +++ b/src/gleam_community/maths/elementary.gleam @@ -98,14 +98,10 @@ import gleam/option /// /// /// -pub fn acos(x: Float) -> Result(Float, String) { +pub fn acos(x: Float) -> Result(Float, Nil) { case x >=. -1.0 && x <=. 1.0 { - True -> - do_acos(x) - |> Ok - False -> - "Invalid input argument: x >= -1 or x <= 1. Valid input is -1. <= x <= 1." - |> Error + True -> Ok(do_acos(x)) + False -> Error(Nil) } } @@ -150,14 +146,10 @@ fn do_acos(a: Float) -> Float /// /// /// -pub fn acosh(x: Float) -> Result(Float, String) { +pub fn acosh(x: Float) -> Result(Float, Nil) { case x >=. 1.0 { - True -> - do_acosh(x) - |> Ok - False -> - "Invalid input argument: x < 1. Valid input is x >= 1." - |> Error + True -> Ok(do_acosh(x)) + False -> Error(Nil) } } @@ -205,14 +197,10 @@ fn do_acosh(a: Float) -> Float /// /// /// -pub fn asin(x: Float) -> Result(Float, String) { +pub fn asin(x: Float) -> Result(Float, Nil) { case x >=. -1.0 && x <=. 1.0 { - True -> - do_asin(x) - |> Ok - False -> - "Invalid input argument: x >= -1 or x <= 1. Valid input is -1. <= x <= 1." - |> Error + True -> Ok(do_asin(x)) + False -> Error(Nil) } } @@ -394,14 +382,10 @@ fn do_atan2(a: Float, b: Float) -> Float /// /// /// -pub fn atanh(x: Float) -> Result(Float, String) { +pub fn atanh(x: Float) -> Result(Float, Nil) { case x >. -1.0 && x <. 1.0 { - True -> - do_atanh(x) - |> Ok - False -> - "Invalid input argument: x > -1 or x < 1. Valid input is -1. < x < 1." - |> Error + True -> Ok(do_atanh(x)) + False -> Error(Nil) } } @@ -753,14 +737,10 @@ fn do_exponential(a: Float) -> Float /// /// /// -pub fn natural_logarithm(x: Float) -> Result(Float, String) { +pub fn natural_logarithm(x: Float) -> Result(Float, Nil) { case x >. 0.0 { - True -> - do_natural_logarithm(x) - |> Ok - False -> - "Invalid input argument: x <= 0. Valid input is x > 0." - |> Error + True -> Ok(do_natural_logarithm(x)) + False -> Error(Nil) } } @@ -810,30 +790,19 @@ fn do_natural_logarithm(a: Float) -> Float /// /// /// -pub fn logarithm(x: Float, base: option.Option(Float)) -> Result(Float, String) { - case x >. 0.0 { - True -> - case base { - option.Some(a) -> - case a >. 0.0 && a != 1.0 { - True -> { - // Apply the "change of base formula" - let assert Ok(numerator) = logarithm_10(x) - let assert Ok(denominator) = logarithm_10(a) - numerator /. denominator - |> Ok - } - False -> - "Invalid input argument: base <= 0 or base == 1. Valid input is base > 0 and base != 1." - |> Error - } - _ -> - "Invalid input argument: base <= 0 or base == 1. Valid input is base > 0 and base != 1." - |> Error +pub fn logarithm(x: Float, base: option.Option(Float)) -> Result(Float, Nil) { + case x >. 0.0, base { + True, option.Some(a) -> + case a >. 0.0 && a != 1.0 { + False -> Error(Nil) + True -> { + // Apply the "change of base formula" + let assert Ok(numerator) = logarithm_10(x) + let assert Ok(denominator) = logarithm_10(a) + Ok(numerator /. denominator) + } } - _ -> - "Invalid input argument: x <= 0. Valid input is x > 0." - |> Error + _, _ -> Error(Nil) } } @@ -877,14 +846,10 @@ pub fn logarithm(x: Float, base: option.Option(Float)) -> Result(Float, String) /// /// /// -pub fn logarithm_2(x: Float) -> Result(Float, String) { +pub fn logarithm_2(x: Float) -> Result(Float, Nil) { case x >. 0.0 { - True -> - do_logarithm_2(x) - |> Ok - False -> - "Invalid input argument: x <= 0. Valid input is x > 0." - |> Error + True -> Ok(do_logarithm_2(x)) + False -> Error(Nil) } } @@ -932,14 +897,10 @@ fn do_logarithm_2(a: Float) -> Float /// /// /// -pub fn logarithm_10(x: Float) -> Result(Float, String) { +pub fn logarithm_10(x: Float) -> Result(Float, Nil) { case x >. 0.0 { - True -> - do_logarithm_10(x) - |> Ok - False -> - "Invalid input argument: x <= 0. Valid input is x > 0." - |> Error + True -> Ok(do_logarithm_10(x)) + False -> Error(Nil) } } @@ -993,7 +954,7 @@ fn do_logarithm_10(a: Float) -> Float /// /// /// -pub fn power(x: Float, y: Float) -> Result(Float, String) { +pub fn power(x: Float, y: Float) -> Result(Float, Nil) { let fractional = do_ceiling(y) -. y >. 0.0 // In the following check: // 1. If the base (x) is negative and the exponent (y) is fractional @@ -1002,9 +963,7 @@ pub fn power(x: Float, y: Float) -> Result(Float, String) { // expression is equivalent to the exponent (y) divided by 0 and an // error should be returned case { x <. 0.0 && fractional } || { x == 0.0 && y <. 0.0 } { - True -> - "Invalid input argument: x < 0 and y is fractional or x = 0 and y < 0." - |> Error + True -> Error(Nil) False -> do_power(x, y) |> Ok @@ -1055,19 +1014,13 @@ fn do_ceiling(a: Float) -> Float /// /// /// -pub fn square_root(x: Float) -> Result(Float, String) { +pub fn square_root(x: Float) -> Result(Float, Nil) { // In the following check: // 1. If x is negative then return an error as it will otherwise be an // imaginary number case x <. 0.0 { - True -> - "Invalid input argument: x < 0." - |> Error - False -> { - let assert Ok(result) = power(x, 1.0 /. 2.0) - result - |> Ok - } + True -> Error(Nil) + False -> power(x, 1.0 /. 2.0) } } @@ -1107,19 +1060,13 @@ pub fn square_root(x: Float) -> Result(Float, String) { /// /// /// -pub fn cube_root(x: Float) -> Result(Float, String) { +pub fn cube_root(x: Float) -> Result(Float, Nil) { // In the following check: // 1. If x is negative then return an error as it will otherwise be an // imaginary number case x <. 0.0 { - True -> - "Invalid input argument: x < 0." - |> Error - False -> { - let assert Ok(result) = power(x, 1.0 /. 3.0) - result - |> Ok - } + True -> Error(Nil) + False -> power(x, 1.0 /. 3.0) } } @@ -1162,25 +1109,13 @@ pub fn cube_root(x: Float) -> Result(Float, String) { /// /// /// -pub fn nth_root(x: Float, n: Int) -> Result(Float, String) { +pub fn nth_root(x: Float, n: Int) -> Result(Float, Nil) { // In the following check: // 1. If x is negative then return an error as it will otherwise be an // imaginary number - case x <. 0.0 { - True -> - "Invalid input argument: x < 0. Valid input is x > 0" - |> Error - False -> - case n >= 1 { - True -> { - let assert Ok(result) = power(x, 1.0 /. int.to_float(n)) - result - |> Ok - } - False -> - "Invalid input argument: n < 1. Valid input is n >= 2." - |> Error - } + case x >=. 0.0 && n >= 1 { + True -> power(x, 1.0 /. int.to_float(n)) + False -> Error(Nil) } } diff --git a/src/gleam_community/maths/metrics.gleam b/src/gleam_community/maths/metrics.gleam index dd4dd7a..6c8959c 100644 --- a/src/gleam_community/maths/metrics.gleam +++ b/src/gleam_community/maths/metrics.gleam @@ -59,6 +59,7 @@ import gleam/int import gleam/list import gleam/option import gleam/pair +import gleam/result import gleam/set import gleam_community/maths/arithmetics import gleam_community/maths/conversion @@ -72,21 +73,15 @@ fn validate_lists( xarr: List(Float), yarr: List(Float), weights: option.Option(List(Float)), -) -> Result(Bool, String) { +) -> Result(Bool, Nil) { case xarr, yarr { - [], _ -> - "Invalid input argument: The list xarr is empty." - |> Error - _, [] -> - "Invalid input argument: The list yarr is empty." - |> Error + [], _ -> Error(Nil) + _, [] -> Error(Nil) _, _ -> { let xarr_length = list.length(xarr) let yarr_length = list.length(yarr) case xarr_length == yarr_length, weights { - False, _ -> - "Invalid input argument: length(xarr) != length(yarr). Valid input is when length(xarr) == length(yarr)." - |> Error + False, _ -> Error(Nil) True, option.None -> { True |> Ok @@ -97,9 +92,7 @@ fn validate_lists( True -> { validate_weights(warr) } - False -> - "Invalid input argument: length(weights) != length(xarr) and length(weights) != length(yarr). Valid input is when length(weights) == length(xarr) == length(yarr)." - |> Error + False -> Error(Nil) } } } @@ -107,16 +100,12 @@ fn validate_lists( } } -fn validate_weights(warr: List(Float)) -> Result(Bool, String) { +fn validate_weights(warr: List(Float)) -> Result(Bool, Nil) { // Check that all the given weights are positive let assert Ok(minimum) = piecewise.list_minimum(warr, float.compare) case minimum >=. 0.0 { - False -> - "Invalid input argument: One or more weights are negative. Valid input is when all weights are >= 0." - |> Error - True -> - True - |> Ok + False -> Error(Nil) + True -> Ok(True) } } @@ -174,7 +163,7 @@ pub fn norm( arr: List(Float), p: Float, weights: option.Option(List(Float)), -) -> Result(Float, String) { +) -> Result(Float, Nil) { case arr, weights { [], _ -> 0.0 @@ -221,10 +210,7 @@ pub fn norm( |> Error } } - False -> { - "Invalid input argument: length(weights) != length(arr). Valid input is when length(weights) == length(arr)." - |> Error - } + False -> Error(Nil) } } } @@ -286,7 +272,7 @@ pub fn manhattan_distance( xarr: List(Float), yarr: List(Float), weights: option.Option(List(Float)), -) -> Result(Float, String) { +) -> Result(Float, Nil) { minkowski_distance(xarr, yarr, 1.0, weights) } @@ -354,26 +340,17 @@ pub fn minkowski_distance( yarr: List(Float), p: Float, weights: option.Option(List(Float)), -) -> Result(Float, String) { - case validate_lists(xarr, yarr, weights) { - Error(msg) -> - msg - |> Error - Ok(_) -> { - case p <. 1.0 { - True -> - "Invalid input argument: p < 1. Valid input is p >= 1." - |> Error - False -> { - let differences = - list.zip(xarr, yarr) - |> list.map(fn(tuple) { pair.first(tuple) -. pair.second(tuple) }) - - let assert Ok(result) = norm(differences, p, weights) - result - |> Ok - } - } +) -> Result(Float, Nil) { + use _ <- result.try(validate_lists(xarr, yarr, weights)) + case p <. 1.0 { + True -> Error(Nil) + False -> { + let differences: List(Float) = + list.zip(xarr, yarr) + |> list.map(fn(tuple: #(Float, Float)) -> Float { + pair.first(tuple) -. pair.second(tuple) + }) + norm(differences, p, weights) } } } @@ -434,7 +411,7 @@ pub fn euclidean_distance( xarr: List(Float), yarr: List(Float), weights: option.Option(List(Float)), -) -> Result(Float, String) { +) -> Result(Float, Nil) { minkowski_distance(xarr, yarr, 2.0, weights) } @@ -484,7 +461,7 @@ pub fn euclidean_distance( pub fn chebyshev_distance( xarr: List(Float), yarr: List(Float), -) -> Result(Float, String) { +) -> Result(Float, Nil) { case validate_lists(xarr, yarr, option.None) { Error(msg) -> msg @@ -540,11 +517,9 @@ pub fn chebyshev_distance( /// /// /// -pub fn mean(arr: List(Float)) -> Result(Float, String) { +pub fn mean(arr: List(Float)) -> Result(Float, Nil) { case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error + [] -> Error(Nil) _ -> arr |> arithmetics.float_sum(option.None) @@ -664,34 +639,27 @@ fn do_median( /// /// /// -pub fn variance(arr: List(Float), ddof: Int) -> Result(Float, String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> - case ddof < 0 { - True -> - "Invalid input argument: ddof < 0. Valid input is ddof >= 0." - |> Error - False -> { - let assert Ok(mean) = mean(arr) - arr - |> list.map(fn(a) { - let assert Ok(result) = elementary.power(a -. mean, 2.0) - result - }) - |> arithmetics.float_sum(option.None) - |> fn(a) { - a - /. { - conversion.int_to_float(list.length(arr)) - -. conversion.int_to_float(ddof) - } - } - |> Ok +pub fn variance(arr: List(Float), ddof: Int) -> Result(Float, Nil) { + case arr, ddof { + [], _ -> Error(Nil) + _, _ if ddof < 0 -> Error(Nil) + _, _ -> { + let assert Ok(mean) = mean(arr) + arr + |> list.map(fn(a: Float) -> Float { + let assert Ok(result) = elementary.power(a -. mean, 2.0) + result + }) + |> arithmetics.float_sum(option.None) + |> fn(a: Float) -> Float { + a + /. { + conversion.int_to_float(list.length(arr)) + -. conversion.int_to_float(ddof) } } + |> Ok + } } } @@ -741,25 +709,18 @@ pub fn variance(arr: List(Float), ddof: Int) -> Result(Float, String) { /// /// /// -pub fn standard_deviation(arr: List(Float), ddof: Int) -> Result(Float, String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> - case ddof < 0 { - True -> - "Invalid input argument: ddof < 0. Valid input is ddof >= 0." - |> Error - False -> { - let assert Ok(variance) = variance(arr, ddof) - // The computed variance will always be positive - // So an error should never be returned - let assert Ok(stdev) = elementary.square_root(variance) - stdev - |> Ok - } - } +pub fn standard_deviation(arr: List(Float), ddof: Int) -> Result(Float, Nil) { + case arr, ddof { + [], _ -> Error(Nil) + _, _ if ddof < 0 -> Error(Nil) + _, _ -> { + let assert Ok(variance) = variance(arr, ddof) + // The computed variance will always be positive + // So an error should never be returned + let assert Ok(stdev) = elementary.square_root(variance) + stdev + |> Ok + } } } @@ -924,7 +885,7 @@ pub fn tversky_index( yset: set.Set(a), alpha: Float, beta: Float, -) -> Result(Float, String) { +) -> Result(Float, Nil) { case alpha >=. 0.0, beta >=. 0.0 { True, True -> { let intersection = @@ -943,18 +904,7 @@ pub fn tversky_index( /. { intersection +. alpha *. difference1 +. beta *. difference2 } |> Ok } - False, True -> { - "Invalid input argument: alpha < 0. Valid input is alpha >= 0." - |> Error - } - True, False -> { - "Invalid input argument: beta < 0. Valid input is beta >= 0." - |> Error - } - _, _ -> { - "Invalid input argument: alpha < 0 and beta < 0. Valid input is alpha >= 0 and beta >= 0." - |> Error - } + _, _ -> Error(Nil) } } @@ -1077,7 +1027,7 @@ pub fn cosine_similarity( xarr: List(Float), yarr: List(Float), weights: option.Option(List(Float)), -) -> Result(Float, String) { +) -> Result(Float, Nil) { case validate_lists(xarr, yarr, weights) { Error(msg) -> msg @@ -1173,7 +1123,7 @@ pub fn canberra_distance( xarr: List(Float), yarr: List(Float), weights: option.Option(List(Float)), -) -> Result(Float, String) { +) -> Result(Float, Nil) { case validate_lists(xarr, yarr, weights) { Error(msg) -> msg @@ -1266,7 +1216,7 @@ pub fn braycurtis_distance( xarr: List(Float), yarr: List(Float), weights: option.Option(List(Float)), -) -> Result(Float, String) { +) -> Result(Float, Nil) { case validate_lists(xarr, yarr, weights) { Error(msg) -> msg diff --git a/src/gleam_community/maths/piecewise.gleam b/src/gleam_community/maths/piecewise.gleam index fdfc4fb..cebdc38 100644 --- a/src/gleam_community/maths/piecewise.gleam +++ b/src/gleam_community/maths/piecewise.gleam @@ -949,11 +949,9 @@ pub fn minmax(x: a, y: a, compare: fn(a, a) -> order.Order) { pub fn list_minimum( arr: List(a), compare: fn(a, a) -> order.Order, -) -> Result(a, String) { +) -> Result(a, Nil) { case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error + [] -> Error(Nil) [x, ..rest] -> Ok( list.fold(rest, x, fn(acc, element) { @@ -1003,11 +1001,9 @@ pub fn list_minimum( pub fn list_maximum( arr: List(a), compare: fn(a, a) -> order.Order, -) -> Result(a, String) { +) -> Result(a, Nil) { case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error + [] -> Error(Nil) [x, ..rest] -> Ok( list.fold(rest, x, fn(acc, element) { @@ -1063,11 +1059,9 @@ pub fn list_maximum( pub fn arg_minimum( arr: List(a), compare: fn(a, a) -> order.Order, -) -> Result(List(Int), String) { +) -> Result(List(Int), Nil) { case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error + [] -> Error(Nil) _ -> { let assert Ok(min) = arr @@ -1133,11 +1127,9 @@ pub fn arg_minimum( pub fn arg_maximum( arr: List(a), compare: fn(a, a) -> order.Order, -) -> Result(List(Int), String) { +) -> Result(List(Int), Nil) { case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error + [] -> Error(Nil) _ -> { let assert Ok(max) = arr @@ -1203,11 +1195,9 @@ pub fn arg_maximum( pub fn extrema( arr: List(a), compare: fn(a, a) -> order.Order, -) -> Result(#(a, a), String) { +) -> Result(#(a, a), Nil) { case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error + [] -> Error(Nil) [x, ..rest] -> Ok( list.fold(rest, #(x, x), fn(acc, element) { diff --git a/src/gleam_community/maths/predicates.gleam b/src/gleam_community/maths/predicates.gleam index 4681e3b..73e5743 100644 --- a/src/gleam_community/maths/predicates.gleam +++ b/src/gleam_community/maths/predicates.gleam @@ -135,7 +135,7 @@ fn float_absolute_difference(a: Float, b: Float) -> Float { /// let rtol = 0.01 /// let atol = 0.10 /// predicates.all_close(xarr, yarr, rtol, atol) -/// |> fn(zarr), String)) { +/// |> fn(zarr: Result(List(Bool), Nil)) -> Result(Bool, Nil) { /// case zarr { /// Ok(arr) -> /// arr @@ -159,13 +159,11 @@ pub fn all_close( yarr: List(Float), rtol: Float, atol: Float, -) -> Result(List(Bool), String) { +) -> Result(List(Bool), Nil) { let xlen = list.length(xarr) let ylen = list.length(yarr) case xlen == ylen { - False -> - "Invalid input argument: length(xarr) != length(yarr). Valid input is when length(xarr) == length(yarr)." - |> Error + False -> Error(Nil) True -> list.zip(xarr, yarr) |> list.map(fn(z) { is_close(pair.first(z), pair.second(z), rtol, atol) }) diff --git a/src/gleam_community/maths/sequences.gleam b/src/gleam_community/maths/sequences.gleam index 62c5301..c801184 100644 --- a/src/gleam_community/maths/sequences.gleam +++ b/src/gleam_community/maths/sequences.gleam @@ -160,7 +160,7 @@ pub fn linear_space( stop: Float, num: Int, endpoint: Bool, -) -> Result(iterator.Iterator(Float), String) { +) -> Result(iterator.Iterator(Float), Nil) { let direction = case start <=. stop { True -> 1.0 False -> -1.0 @@ -184,9 +184,7 @@ pub fn linear_space( }) |> Ok } - False -> - "Invalid input: num < 1. Valid input is num >= 1." - |> Error + False -> Error(Nil) } } @@ -241,7 +239,7 @@ pub fn logarithmic_space( num: Int, endpoint: Bool, base: Float, -) -> Result(iterator.Iterator(Float), String) { +) -> Result(iterator.Iterator(Float), Nil) { case num > 0 { True -> { let assert Ok(linspace) = linear_space(start, stop, num, endpoint) @@ -252,9 +250,7 @@ pub fn logarithmic_space( }) |> Ok } - False -> - "Invalid input: num < 1. Valid input is num >= 1." - |> Error + False -> Error(Nil) } } @@ -316,11 +312,9 @@ pub fn geometric_space( stop: Float, num: Int, endpoint: Bool, -) -> Result(iterator.Iterator(Float), String) { +) -> Result(iterator.Iterator(Float), Nil) { case start == 0.0 || stop == 0.0 { - True -> - "Invalid input: Neither 'start' nor 'stop' can be zero, as they must be non-zero for logarithmic calculations." - |> Error + True -> Error(Nil) False -> case num > 0 { True -> { @@ -328,9 +322,7 @@ pub fn geometric_space( let assert Ok(log_stop) = elementary.logarithm_10(stop) logarithmic_space(log_start, log_stop, num, endpoint, 10.0) } - False -> - "Invalid input: num < 1. Valid input is num >= 1." - |> Error + False -> Error(Nil) } } } diff --git a/src/gleam_community/maths/special.gleam b/src/gleam_community/maths/special.gleam index a3f0136..6422709 100644 --- a/src/gleam_community/maths/special.gleam +++ b/src/gleam_community/maths/special.gleam @@ -163,7 +163,7 @@ fn gamma_lanczos(x: Float) -> Float { /// /// /// -pub fn incomplete_gamma(a: Float, x: Float) -> Result(Float, String) { +pub fn incomplete_gamma(a: Float, x: Float) -> Result(Float, Nil) { case a >. 0.0 && x >=. 0.0 { True -> { let assert Ok(v) = elementary.power(x, a) @@ -173,9 +173,7 @@ pub fn incomplete_gamma(a: Float, x: Float) -> Result(Float, String) { |> Ok } - False -> - "Invalid input argument: a <= 0 or x < 0. Valid input is a > 0 and x >= 0." - |> Error + False -> Error(Nil) } } diff --git a/test/gleam_community/maths/predicates_test.gleam b/test/gleam_community/maths/predicates_test.gleam index c9e2c5f..e544eb5 100644 --- a/test/gleam_community/maths/predicates_test.gleam +++ b/test/gleam_community/maths/predicates_test.gleam @@ -23,7 +23,7 @@ pub fn float_list_all_close_test() { let rtol = 0.01 let atol = 0.1 predicates.all_close(xarr, yarr, rtol, atol) - |> fn(zarr) { + |> fn(zarr: Result(List(Bool), Nil)) -> Result(Bool, Nil) { case zarr { Ok(arr) -> arr