-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add equivalence and predicate modules
- Loading branch information
1 parent
41c8d1f
commit 56944d9
Showing
8 changed files
with
465 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ on: | |
pull_request: | ||
|
||
jobs: | ||
test: | ||
tests: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# This file was generated by Gleam | ||
# You typically do not need to edit this file | ||
|
||
packages = [ | ||
{ name = "gleam_stdlib", version = "0.37.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "5398BD6C2ABA17338F676F42F404B9B7BABE1C8DC7380031ACB05BBE1BCF3742" }, | ||
{ name = "gleeunit", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "72CDC3D3F719478F26C4E2C5FED3E657AC81EC14A47D2D2DEBB8693CA3220C3B" }, | ||
] | ||
|
||
[requirements] | ||
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" } | ||
gleeunit = { version = ">= 1.0.0 and < 2.0.0" } |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
pub type Equivalence(a) = | ||
fn(a, a) -> Bool | ||
|
||
/// Create a new equivalence that always returns `True`. | ||
/// | ||
/// This is sometimes called the trivial or universal equivalence. | ||
/// | ||
pub fn trivial() -> Equivalence(a) { | ||
fn(_, _) -> Bool { True } | ||
} | ||
|
||
/// Combine two equivalences into a new equivalence that returns `True` if both | ||
/// equivalences return `True`. | ||
/// | ||
pub fn and(first: Equivalence(a), second: Equivalence(a)) -> Equivalence(a) { | ||
fn(value: a, other: a) -> Bool { first(value, other) && second(value, other) } | ||
} | ||
|
||
/// Combine two equivalences into a new equivalence that returns `True` if either | ||
/// equivalence returns `True`. | ||
/// | ||
pub fn or(first: Equivalence(a), second: Equivalence(a)) -> Equivalence(a) { | ||
fn(value: a, other: a) -> Bool { first(value, other) || second(value, other) } | ||
} | ||
|
||
/// Negate an equivalence to create a new equivalence that returns `True` if the | ||
/// original equivalence returns `False`. | ||
/// | ||
pub fn not(eq: Equivalence(a)) -> Equivalence(a) { | ||
fn(value: a, other: a) -> Bool { !eq(value, other) } | ||
} | ||
|
||
/// Create a new equivalence for a list of values based on the given equivalence. | ||
/// | ||
pub fn list(eq: Equivalence(a)) -> Equivalence(List(a)) { | ||
fn(values: List(a), others: List(a)) -> Bool { | ||
case values, others { | ||
[], [] -> True | ||
[value, ..values], [other, ..others] -> { | ||
eq(value, other) && list(eq)(values, others) | ||
} | ||
_, _ -> False | ||
} | ||
} | ||
} | ||
|
||
/// Create a new equivalence for a pair of values based on the given equivalences. | ||
/// | ||
pub fn pair( | ||
first: Equivalence(a), | ||
second: Equivalence(b), | ||
) -> Equivalence(#(a, b)) { | ||
fn(value: #(a, b), other: #(a, b)) -> Bool { | ||
case value, other { | ||
#(value1, value2), #(other1, other2) -> { | ||
first(value1, other1) && second(value2, other2) | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// Map the input of an equivalence to create a new equivalence. | ||
/// | ||
pub fn map_input( | ||
over eq: Equivalence(a), | ||
with fun: fn(b) -> a, | ||
) -> Equivalence(b) { | ||
fn(value: b, other: b) -> Bool { eq(fun(value), fun(other)) } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import gleam/list | ||
|
||
pub type Predicate(a) = | ||
fn(a) -> Bool | ||
|
||
/// Create a new predicate that always returns `True`. | ||
/// | ||
pub fn always() -> Predicate(a) { | ||
fn(_) -> Bool { True } | ||
} | ||
|
||
/// Create a new predicate that always returns `False`. | ||
/// | ||
pub fn never() -> Predicate(a) { | ||
fn(_) -> Bool { False } | ||
} | ||
|
||
/// Combine two predicates together into a new predicate that returns `True` if | ||
/// both predicates return `True`. | ||
/// | ||
pub fn and(first: Predicate(a), second: Predicate(a)) -> Predicate(a) { | ||
fn(value: a) -> Bool { first(value) && second(value) } | ||
} | ||
|
||
/// Combine two predicates together into a new predicate that returns `True` if | ||
/// either predicate returns `True`. | ||
/// | ||
pub fn or(first: Predicate(a), second: Predicate(a)) -> Predicate(a) { | ||
fn(value: a) -> Bool { first(value) || second(value) } | ||
} | ||
|
||
/// Negate a predicate. | ||
/// | ||
pub fn not(p: Predicate(a)) -> Predicate(a) { | ||
fn(value: a) -> Bool { !p(value) } | ||
} | ||
|
||
/// Combine a list of predicates together into a new predicate that returns `True` | ||
/// if all predicates return `True`. | ||
/// | ||
pub fn every(ps: List(Predicate(a))) -> Predicate(a) { | ||
case ps { | ||
[] -> fn(_) -> Bool { True } | ||
[p, ..ps] -> fn(value: a) -> Bool { p(value) && every(ps)(value) } | ||
} | ||
} | ||
|
||
/// Combine a list of predicates together into a new predicate that returns `True` | ||
/// if any predicate returns `True`. | ||
/// | ||
pub fn some(ps: List(Predicate(a))) -> Predicate(a) { | ||
case ps { | ||
[] -> fn(_) -> Bool { False } | ||
[p, ..ps] -> fn(value: a) -> Bool { p(value) || some(ps)(value) } | ||
} | ||
} | ||
|
||
/// Create a new predicate that returns `True` if it returns `True` for every | ||
/// element in a list. | ||
/// | ||
pub fn all(p: Predicate(a)) -> Predicate(List(a)) { | ||
fn(a: List(a)) -> Bool { | ||
a | ||
|> list.all(p) | ||
} | ||
} | ||
|
||
/// Create a new predicate that returns `True` if it returns `True` for any | ||
/// element in a list. | ||
/// | ||
pub fn any(p: Predicate(a)) -> Predicate(List(a)) { | ||
fn(a: List(a)) -> Bool { | ||
a | ||
|> list.any(p) | ||
} | ||
} | ||
|
||
/// Map the input of a predicate to create a new predicate. | ||
/// | ||
pub fn map_input(over p: Predicate(a), with fun: fn(b) -> a) -> Predicate(b) { | ||
fn(b: b) -> Bool { p(fun(b)) } | ||
} |
Oops, something went wrong.