diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | src/gleam/order.gleam | 46 | ||||
-rw-r--r-- | test/gleam/order_test.gleam | 34 |
3 files changed, 81 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 20700cb..69a1323 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- The `order` module gains the `break_tie` and `lazy_break_tie` functions. - `list.LengthMismatch` has been removed. - The mistakenly public `bit_array.do_inspect` function has been removed. diff --git a/src/gleam/order.gleam b/src/gleam/order.gleam index ad25c94..e20ea8c 100644 --- a/src/gleam/order.gleam +++ b/src/gleam/order.gleam @@ -133,3 +133,49 @@ pub fn min(a: Order, b: Order) -> Order { pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order { fn(a, b) { orderer(b, a) } } + +/// Return a fallback `Order` in case the first argument is `Eq`. +/// +/// ## Examples +/// +/// ```gleam +/// import gleam/int +/// +/// break_tie(in: int.compare(1, 1), with: Lt) +/// // -> Lt +/// +/// break_tie(in: int.compare(1, 0), with: Eq) +/// // -> Gt +/// ``` +/// +pub fn break_tie(in order: Order, with other: Order) -> Order { + case order { + Lt | Gt -> order + Eq -> other + } +} + +/// Invokes a fallback function returning an `Order` in case the first argument +/// is `Eq`. +/// +/// This can be useful when the fallback comparison might be expensive and it +/// needs to be delayed until strictly necessary. +/// +/// ## Examples +/// +/// ```gleam +/// import gleam/int +/// +/// lazy_break_tie(in: int.compare(1, 1), with: fn() { Lt }) +/// // -> Lt +/// +/// lazy_break_tie(in: int.compare(1, 0), with: fn() { Eq }) +/// // -> Gt +/// ``` +/// +pub fn lazy_break_tie(in order: Order, with comparison: fn() -> Order) -> Order { + case order { + Lt | Gt -> order + Eq -> comparison() + } +} diff --git a/test/gleam/order_test.gleam b/test/gleam/order_test.gleam index e9929d3..b2f66e0 100644 --- a/test/gleam/order_test.gleam +++ b/test/gleam/order_test.gleam @@ -117,3 +117,37 @@ pub fn reverse_test() { |> list.sort(by: order.reverse(int.compare)) |> should.equal([5, 4, 1]) } + +pub fn break_tie_test() { + order.break_tie(in: Eq, with: Lt) + |> should.equal(Lt) + + order.break_tie(in: Eq, with: Gt) + |> should.equal(Gt) + + order.break_tie(in: Eq, with: Eq) + |> should.equal(Eq) + + order.break_tie(in: Gt, with: Lt) + |> should.equal(Gt) + + order.break_tie(in: Lt, with: Gt) + |> should.equal(Lt) +} + +pub fn lazy_break_tie_test() { + order.lazy_break_tie(in: Eq, with: fn() { Lt }) + |> should.equal(Lt) + + order.lazy_break_tie(in: Eq, with: fn() { Gt }) + |> should.equal(Gt) + + order.lazy_break_tie(in: Eq, with: fn() { Eq }) + |> should.equal(Eq) + + order.lazy_break_tie(in: Gt, with: fn() { panic }) + |> should.equal(Gt) + + order.lazy_break_tie(in: Lt, with: fn() { panic }) + |> should.equal(Lt) +} |