aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/gleam/order.gleam46
-rw-r--r--test/gleam/order_test.gleam34
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)
+}