make adding lenses be const
parent
ca9d8de37f
commit
c3d76f109f
|
@ -6,7 +6,9 @@ ergonomic lenses in rust
|
||||||
|
|
||||||
it does *not* implement the operators, as it's not really a thing we can do in rust
|
it does *not* implement the operators, as it's not really a thing we can do in rust
|
||||||
|
|
||||||
does bringing lenses into rust actually make sense? probably not, but it was fun to implement
|
you will need nightly for this library to work, as it uses a bunch of unstable features. they're technically not *critical*, but i think not having them reduces the ergonomics too much
|
||||||
|
|
||||||
|
does bringing lenses into rust actually make sense? probably not, but it was fun to implement so who can say
|
||||||
|
|
||||||
## example
|
## example
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::{
|
||||||
prisms::{Prism, PrismPreview},
|
prisms::{Prism, PrismPreview},
|
||||||
traversals::{Traversal, TraversalOver, TraversalTraverse},
|
traversals::{Traversal, TraversalOver, TraversalTraverse},
|
||||||
};
|
};
|
||||||
|
use std::ops::Add;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Combination<A, B>(A, B);
|
pub struct Combination<A, B>(A, B);
|
||||||
|
@ -10,7 +11,7 @@ pub struct Combination<A, B>(A, B);
|
||||||
// additions
|
// additions
|
||||||
|
|
||||||
// lens + lens
|
// lens + lens
|
||||||
impl<A, B> std::ops::Add<Lens<B>> for Lens<A> {
|
impl<A, B> const Add<Lens<B>> for Lens<A> {
|
||||||
type Output = Lens<Combination<Lens<A>, Lens<B>>>;
|
type Output = Lens<Combination<Lens<A>, Lens<B>>>;
|
||||||
|
|
||||||
fn add(self, rhs: Lens<B>) -> Self::Output {
|
fn add(self, rhs: Lens<B>) -> Self::Output {
|
||||||
|
@ -18,7 +19,7 @@ impl<A, B> std::ops::Add<Lens<B>> for Lens<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// prism + prism
|
// prism + prism
|
||||||
impl<A, B> std::ops::Add<Prism<B>> for Prism<A> {
|
impl<A, B> const Add<Prism<B>> for Prism<A> {
|
||||||
type Output = Prism<Combination<Prism<A>, Prism<B>>>;
|
type Output = Prism<Combination<Prism<A>, Prism<B>>>;
|
||||||
|
|
||||||
fn add(self, rhs: Prism<B>) -> Self::Output {
|
fn add(self, rhs: Prism<B>) -> Self::Output {
|
||||||
|
@ -26,7 +27,7 @@ impl<A, B> std::ops::Add<Prism<B>> for Prism<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// traversal + traversal
|
// traversal + traversal
|
||||||
impl<A, B> std::ops::Add<Traversal<B>> for Traversal<A> {
|
impl<A, B> const Add<Traversal<B>> for Traversal<A> {
|
||||||
type Output = Traversal<Combination<Traversal<A>, Traversal<B>>>;
|
type Output = Traversal<Combination<Traversal<A>, Traversal<B>>>;
|
||||||
|
|
||||||
fn add(self, rhs: Traversal<B>) -> Self::Output {
|
fn add(self, rhs: Traversal<B>) -> Self::Output {
|
||||||
|
@ -34,7 +35,7 @@ impl<A, B> std::ops::Add<Traversal<B>> for Traversal<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// traversal + lens
|
// traversal + lens
|
||||||
impl<A, B> std::ops::Add<Lens<B>> for Traversal<A> {
|
impl<A, B> const Add<Lens<B>> for Traversal<A> {
|
||||||
type Output = Traversal<Combination<Traversal<A>, Traversal<Lens<B>>>>;
|
type Output = Traversal<Combination<Traversal<A>, Traversal<Lens<B>>>>;
|
||||||
|
|
||||||
fn add(self, rhs: Lens<B>) -> Self::Output {
|
fn add(self, rhs: Lens<B>) -> Self::Output {
|
||||||
|
@ -42,7 +43,7 @@ impl<A, B> std::ops::Add<Lens<B>> for Traversal<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// lens + traversal
|
// lens + traversal
|
||||||
impl<A, B> std::ops::Add<Traversal<B>> for Lens<A> {
|
impl<A, B> const Add<Traversal<B>> for Lens<A> {
|
||||||
type Output = Traversal<Combination<Traversal<Lens<A>>, Traversal<B>>>;
|
type Output = Traversal<Combination<Traversal<Lens<A>>, Traversal<B>>>;
|
||||||
|
|
||||||
fn add(self, rhs: Traversal<B>) -> Self::Output {
|
fn add(self, rhs: Traversal<B>) -> Self::Output {
|
||||||
|
@ -50,7 +51,7 @@ impl<A, B> std::ops::Add<Traversal<B>> for Lens<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// traversal + prism
|
// traversal + prism
|
||||||
impl<A, B> std::ops::Add<Prism<B>> for Traversal<A> {
|
impl<A, B> const Add<Prism<B>> for Traversal<A> {
|
||||||
type Output = Traversal<Combination<Traversal<A>, Traversal<Prism<B>>>>;
|
type Output = Traversal<Combination<Traversal<A>, Traversal<Prism<B>>>>;
|
||||||
|
|
||||||
fn add(self, rhs: Prism<B>) -> Self::Output {
|
fn add(self, rhs: Prism<B>) -> Self::Output {
|
||||||
|
@ -58,7 +59,7 @@ impl<A, B> std::ops::Add<Prism<B>> for Traversal<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// prism + traversal
|
// prism + traversal
|
||||||
impl<A, B> std::ops::Add<Traversal<B>> for Prism<A> {
|
impl<A, B> const Add<Traversal<B>> for Prism<A> {
|
||||||
type Output = Traversal<Combination<Traversal<Prism<A>>, Traversal<B>>>;
|
type Output = Traversal<Combination<Traversal<Prism<A>>, Traversal<B>>>;
|
||||||
|
|
||||||
fn add(self, rhs: Traversal<B>) -> Self::Output {
|
fn add(self, rhs: Traversal<B>) -> Self::Output {
|
||||||
|
@ -66,7 +67,7 @@ impl<A, B> std::ops::Add<Traversal<B>> for Prism<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// lens + prism
|
// lens + prism
|
||||||
impl<A, B> std::ops::Add<Prism<B>> for Lens<A> {
|
impl<A, B> const Add<Prism<B>> for Lens<A> {
|
||||||
type Output = Traversal<Combination<Traversal<Lens<A>>, Traversal<Prism<B>>>>;
|
type Output = Traversal<Combination<Traversal<Lens<A>>, Traversal<Prism<B>>>>;
|
||||||
|
|
||||||
fn add(self, rhs: Prism<B>) -> Self::Output {
|
fn add(self, rhs: Prism<B>) -> Self::Output {
|
||||||
|
@ -74,7 +75,7 @@ impl<A, B> std::ops::Add<Prism<B>> for Lens<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// prism + traversal
|
// prism + traversal
|
||||||
impl<A, B> std::ops::Add<Lens<B>> for Prism<A> {
|
impl<A, B> const Add<Lens<B>> for Prism<A> {
|
||||||
type Output = Traversal<Combination<Traversal<Prism<A>>, Traversal<Lens<B>>>>;
|
type Output = Traversal<Combination<Traversal<Prism<A>>, Traversal<Lens<B>>>>;
|
||||||
|
|
||||||
fn add(self, rhs: Lens<B>) -> Self::Output {
|
fn add(self, rhs: Lens<B>) -> Self::Output {
|
||||||
|
@ -321,4 +322,17 @@ mod tests {
|
||||||
let res = t(thing, |v| v + 1);
|
let res = t(thing, |v| v + 1);
|
||||||
assert_eq!(res, (Some(2), 2));
|
assert_eq!(res, (Some(2), 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_combine_as_const() {
|
||||||
|
use crate::lenses::first::_0Inner;
|
||||||
|
use crate::lenses::Lens;
|
||||||
|
const LENS: Lens<super::Combination<Lens<_0Inner>, Lens<_0Inner>>> = _0 + _0;
|
||||||
|
|
||||||
|
let thing: ((i32, i32), i32) = ((1, 2), 3);
|
||||||
|
|
||||||
|
let r: i32 = LENS(thing);
|
||||||
|
|
||||||
|
assert_eq!(r, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
mod fields;
|
pub mod fields;
|
||||||
|
|
||||||
mod identity;
|
pub mod identity;
|
||||||
pub use identity::id;
|
pub use identity::id;
|
||||||
|
|
||||||
mod first;
|
pub mod first;
|
||||||
pub use first::_0;
|
pub use first::_0;
|
||||||
mod second;
|
pub mod second;
|
||||||
pub use second::_1;
|
pub use second::_1;
|
||||||
mod third;
|
pub mod third;
|
||||||
pub use third::_2;
|
pub use third::_2;
|
||||||
mod fourth;
|
pub mod fourth;
|
||||||
pub use fourth::_3;
|
pub use fourth::_3;
|
||||||
mod fifth;
|
pub mod fifth;
|
||||||
pub use fifth::_4;
|
pub use fifth::_4;
|
||||||
|
|
||||||
mod to;
|
pub mod to;
|
||||||
pub use to::{to, to_from_boxed};
|
pub use to::{to, to_from_boxed};
|
||||||
mod lens;
|
pub mod lens;
|
||||||
pub use lens::{lens, lens_from_boxed};
|
pub use lens::{lens, lens_from_boxed};
|
||||||
|
|
||||||
/// Wrapper type
|
/// Wrapper type
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![feature(unboxed_closures, fn_traits)]
|
#![feature(unboxed_closures, fn_traits, const_trait_impl)]
|
||||||
|
|
||||||
pub mod combinations;
|
pub mod combinations;
|
||||||
mod fns;
|
mod fns;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
mod result;
|
pub mod result;
|
||||||
pub use result::{_Err, _Ok};
|
pub use result::{_Err, _Ok};
|
||||||
|
|
||||||
mod option;
|
pub mod option;
|
||||||
pub use option::{_None, _Some};
|
pub use option::{_None, _Some};
|
||||||
|
|
||||||
/// Wrapper type
|
/// Wrapper type
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
mod both;
|
pub mod both;
|
||||||
pub use both::both;
|
pub use both::both;
|
||||||
|
|
||||||
mod each;
|
pub mod each;
|
||||||
pub use each::each;
|
pub use each::each;
|
||||||
|
|
||||||
mod head;
|
pub mod head;
|
||||||
pub use head::_head;
|
pub use head::_head;
|
||||||
mod tail;
|
pub mod tail;
|
||||||
pub use tail::_tail;
|
pub use tail::_tail;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -62,7 +62,7 @@ where
|
||||||
// all lenses are traversals, so we can freely transform them into a traversal
|
// all lenses are traversals, so we can freely transform them into a traversal
|
||||||
impl<L> Lens<L> {
|
impl<L> Lens<L> {
|
||||||
/// Returns this lens as a traversal
|
/// Returns this lens as a traversal
|
||||||
pub fn to_traversal(self) -> Traversal<Lens<L>> {
|
pub const fn to_traversal(self) -> Traversal<Lens<L>> {
|
||||||
Traversal(self)
|
Traversal(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ where
|
||||||
// all prisms are traversals, so we can freely transform them into a traversal
|
// all prisms are traversals, so we can freely transform them into a traversal
|
||||||
impl<L> Prism<L> {
|
impl<L> Prism<L> {
|
||||||
/// Returns this lens as a traversal
|
/// Returns this lens as a traversal
|
||||||
pub fn to_traversal(self) -> Traversal<Prism<L>> {
|
pub const fn to_traversal(self) -> Traversal<Prism<L>> {
|
||||||
Traversal(self)
|
Traversal(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue