♻️ Replace error types with Nil for better DX with other error-producing functions.

This commit is contained in:
Hayleigh Thompson 2024-08-17 12:37:00 +01:00
parent 6d5241e222
commit 2bd3b76a79
9 changed files with 450 additions and 626 deletions

View file

@ -444,7 +444,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
@ -454,22 +454,16 @@ pub fn float_product(
|> list.fold(1.0, fn(acc: Float, a: Float) -> Float { a *. acc })
|> Ok
_, option.Some(warr) -> {
let results =
list.zip(arr, warr)
|> list.map(fn(a: #(Float, Float)) -> Result(Float, String) {
|> list.map(fn(a: #(Float, Float)) -> Result(Float, Nil) {
pair.first(a)
|> elementary.power(pair.second(a))
})
|> result.all
case results {
Ok(prods) ->
|> result.map(fn(prods) {
prods
|> list.fold(1.0, fn(acc: Float, a: Float) -> Float { a *. acc })
|> Ok
Error(msg) ->
msg
|> Error
}
})
}
}
}

View file

@ -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) {
/// </a>
/// </div>
///
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: Int, x: Int) -> Int { 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(

View file

@ -98,14 +98,10 @@ import gleam/option
/// </a>
/// </div>
///
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
/// </a>
/// </div>
///
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
/// </a>
/// </div>
///
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
/// </a>
/// </div>
///
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
/// </a>
/// </div>
///
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
/// </a>
/// </div>
///
pub fn logarithm(x: Float, base: option.Option(Float)) -> Result(Float, String) {
case x >. 0.0 {
True ->
case base {
option.Some(a) ->
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)
numerator /. denominator
|> Ok
Ok(numerator /. denominator)
}
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
}
_ ->
"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)
/// </a>
/// </div>
///
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
/// </a>
/// </div>
///
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
/// </a>
/// </div>
///
pub fn power(x: Float, y: Float) -> Result(Float, String) {
pub fn power(x: Float, y: Float) -> Result(Float, Nil) {
let fractional: Bool = 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
/// </a>
/// </div>
///
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) {
/// </a>
/// </div>
///
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) {
/// </a>
/// </div>
///
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)
}
}

View file

@ -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: Int = list.length(xarr)
let yarr_length: Int = 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
@ -224,10 +213,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)
}
}
}
@ -289,7 +275,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)
}
@ -357,16 +343,10 @@ 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(_) -> {
) -> Result(Float, Nil) {
use _ <- result.try(validate_lists(xarr, yarr, weights))
case p <. 1.0 {
True ->
"Invalid input argument: p < 1. Valid input is p >= 1."
|> Error
True -> Error(Nil)
False -> {
let differences: List(Float) =
list.zip(xarr, yarr)
@ -374,11 +354,7 @@ pub fn minkowski_distance(
pair.first(tuple) -. pair.second(tuple)
})
let assert Ok(result) = norm(differences, p, weights)
result
|> Ok
}
}
norm(differences, p, weights)
}
}
}
@ -439,7 +415,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)
}
@ -489,7 +465,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
@ -545,11 +521,9 @@ pub fn chebyshev_distance(
/// </a>
/// </div>
///
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)
@ -671,17 +645,11 @@ fn do_median(
/// </a>
/// </div>
///
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 -> {
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 {
@ -700,7 +668,6 @@ pub fn variance(arr: List(Float), ddof: Int) -> Result(Float, String) {
}
}
}
}
/// <div style="text-align: right;">
/// <a href="https://github.com/gleam-community/maths/issues">
@ -748,17 +715,11 @@ pub fn variance(arr: List(Float), ddof: Int) -> Result(Float, String) {
/// </a>
/// </div>
///
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 -> {
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
@ -768,7 +729,6 @@ pub fn standard_deviation(arr: List(Float), ddof: Int) -> Result(Float, String)
}
}
}
}
/// <div style="text-align: right;">
/// <a href="https://github.com/gleam-community/maths/issues">
@ -931,7 +891,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: Float =
@ -950,18 +910,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)
}
}
@ -1084,7 +1033,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
@ -1182,7 +1131,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
@ -1275,7 +1224,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

View file

@ -949,11 +949,9 @@ pub fn minmax(x: a, y: a, compare: fn(a, a) -> order.Order) -> #(a, a) {
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: a, element: a) {
@ -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: a, element: a) {
@ -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: #(a, a), element: a) {

View file

@ -135,7 +135,7 @@ fn float_absolute_difference(a: Float, b: Float) -> Float {
/// let rtol: Float = 0.01
/// let atol: Float = 0.10
/// predicates.all_close(xarr, yarr, rtol, atol)
/// |> fn(zarr: Result(List(Bool), String)) -> Result(Bool, Nil) {
/// |> 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: Int = list.length(xarr)
let ylen: Int = 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: #(Float, Float)) -> Bool {

View file

@ -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: Float = 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)
}
}
}

View file

@ -163,7 +163,7 @@ fn gamma_lanczos(x: Float) -> Float {
/// </a>
/// </div>
///
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)
}
}

View file

@ -23,7 +23,7 @@ pub fn float_list_all_close_test() {
let rtol: Float = 0.01
let atol: Float = 0.1
predicates.all_close(xarr, yarr, rtol, atol)
|> fn(zarr: Result(List(Bool), String)) -> Result(Bool, Nil) {
|> fn(zarr: Result(List(Bool), Nil)) -> Result(Bool, Nil) {
case zarr {
Ok(arr) ->
arr