lerox: Add lerox, a silly little combinator library

This commit is contained in:
John 2023-09-22 23:54:09 -05:00
parent 56b17dea3b
commit 90ef1f542d
4 changed files with 67 additions and 2 deletions

View File

@ -1,5 +1,5 @@
[workspace] [workspace]
members = ["libconlang"] members = ["libconlang", "lerox"]
resolver = "2" resolver = "2"
[workspace.package] [workspace.package]

10
lerox/Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "lerox"
authors.workspace = true
version.workspace = true
edition.workspace = true
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

53
lerox/src/lib.rs Normal file
View File

@ -0,0 +1,53 @@
//! Lerox is a stupid, simple combinator library, part of the Conlang project
pub trait Combinable {
/// Evaluates the [Combinable], and returns whether it is alright
fn is_alright(&self) -> bool;
/// Makes this [Combinable] alright, somehow
fn alright(self) -> Self;
}
pub trait Combinator: Combinable + Sized {
/// If self is alright, runs f(self)
fn and(self, f: impl Fn(Self) -> Self) -> Self {
match self.is_alright() {
true => f(self),
false => self,
}
}
/// If self is not alright, runs f(self)
fn or(self, f: impl FnOnce(Self) -> Self) -> Self {
match self.is_alright() {
true => self,
false => f(self),
}
}
/// Returns the result of running f on self, or if it fails, the original self
fn and_maybe(self, f: impl Fn(Self) -> Self) -> Self
where Self: Clone {
self.clone().and(f).or(|_| self)
}
/// Returns the result of running f on self, or if it fails, runs g on self
fn and_either(self, f: impl Fn(Self) -> Self, g: impl Fn(Self) -> Self) -> Self
where Self: Clone {
self.clone().and(f).or(|_| g(self))
}
/// Repeats the function f on self until it fails
fn and_any(mut self, f: impl Fn(Self) -> Self) -> Self {
while self.is_alright() {
self = self.and(&f)
}
self.alright()
}
/// Repeats the function f on self at least once, then until it fails.
fn and_many(self, f: impl Fn(Self) -> Self) -> Self {
self.and(&f).and_any(f)
}
}
impl<C: Combinable> Combinator for C {}

View File

@ -1,9 +1,11 @@
[package] [package]
name = "conlang" name = "conlang"
authors.workspace = true
version.workspace = true version.workspace = true
edition.workspace = true edition.workspace = true
authors.workspace = true license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
lerox ={ path = "../lerox" }