rename lens to optics

This commit is contained in:
annieversary 2021-11-05 15:55:49 +00:00
parent 30996082ac
commit 037440c845
9 changed files with 103 additions and 89 deletions

View file

@ -1,7 +1,4 @@
use bad_optics::{
lenses::{_0, _1},
*,
};
use bad_optics::lenses::*;
fn main() {
let a = ((1, 2), 3);

View file

@ -1,18 +1,21 @@
use crate::{Lens, LensOver, LensTrait, LensView};
use crate::{
lenses::{LensOver, LensView},
Optics, OpticsTrait,
};
#[derive(Clone, Copy)]
pub struct Combination<A, B>(A, B);
impl<A, B> LensTrait for Combination<A, B> {}
impl<A, B> OpticsTrait for Combination<A, B> {}
impl<A, B> std::ops::Add<Lens<B>> for Lens<A>
impl<A, B> std::ops::Add<Optics<B>> for Optics<A>
where
A: LensTrait,
B: LensTrait,
A: OpticsTrait,
B: OpticsTrait,
{
type Output = Lens<Combination<Lens<A>, Lens<B>>>;
type Output = Optics<Combination<Optics<A>, Optics<B>>>;
fn add(self, rhs: Lens<B>) -> Self::Output {
Lens(Combination(self, rhs))
fn add(self, rhs: Optics<B>) -> Self::Output {
Optics(Combination(self, rhs))
}
}

View file

@ -1,6 +1,9 @@
use crate::{Lens, LensOver, LensView};
use crate::{
lenses::{LensOver, LensView},
Optics,
};
impl<L, A> std::ops::FnOnce<(A,)> for Lens<L>
impl<L, A> std::ops::FnOnce<(A,)> for Optics<L>
where
L: LensView<A>,
{
@ -10,7 +13,7 @@ where
L::view(args.0)
}
}
impl<L, A> std::ops::FnMut<(A,)> for Lens<L>
impl<L, A> std::ops::FnMut<(A,)> for Optics<L>
where
L: LensView<A>,
{
@ -18,7 +21,7 @@ where
L::view(args.0)
}
}
impl<L, A> std::ops::Fn<(A,)> for Lens<L>
impl<L, A> std::ops::Fn<(A,)> for Optics<L>
where
L: LensView<A>,
{
@ -27,7 +30,7 @@ where
}
}
impl<L, A, F> std::ops::FnOnce<(A, F)> for Lens<L>
impl<L, A, F> std::ops::FnOnce<(A, F)> for Optics<L>
where
L: LensOver<A>,
F: FnOnce(L::Field) -> L::Field,
@ -38,7 +41,7 @@ where
L::over(args.0, args.1)
}
}
impl<L, A, F> std::ops::FnMut<(A, F)> for Lens<L>
impl<L, A, F> std::ops::FnMut<(A, F)> for Optics<L>
where
L: LensOver<A>,
F: FnOnce(L::Field) -> L::Field,
@ -47,7 +50,7 @@ where
L::over(args.0, args.1)
}
}
impl<L, A, F> std::ops::Fn<(A, F)> for Lens<L>
impl<L, A, F> std::ops::Fn<(A, F)> for Optics<L>
where
L: LensOver<A>,
F: FnOnce(L::Field) -> L::Field,

View file

@ -1,9 +1,12 @@
use crate::{Lens, LensOver, LensTrait, LensView};
use crate::{
lenses::{LensOver, LensView},
Optics, OpticsTrait,
};
#[derive(Clone, Copy)]
pub struct _0Inner;
pub const _0: Lens<_0Inner> = Lens(_0Inner);
impl LensTrait for _0Inner {}
pub const _0: Optics<_0Inner> = Optics(_0Inner);
impl OpticsTrait for _0Inner {}
macro_rules! make_tuples {
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {

View file

@ -1,10 +1,13 @@
use crate::{LensOver, LensTrait, LensView};
use crate::{
lenses::{LensOver, LensView},
OpticsTrait,
};
#[allow(non_camel_case_types)]
#[derive(Clone, Copy)]
pub struct id;
impl LensTrait for id {}
impl OpticsTrait for id {}
impl<T> LensView<T> for id {
type Field = T;

View file

@ -5,3 +5,55 @@ mod first;
pub use first::_0;
mod second;
pub use second::_1;
use crate::{Optics, OpticsTrait};
/// For lenses that allow viewing
pub trait LensView<T>: OpticsTrait {
type Field;
fn view(thing: T) -> Self::Field;
}
/// For lenses that allow setting
pub trait LensOver<T>: LensView<T> {
fn over<F>(thing: T, f: F) -> T
where
F: FnOnce(Self::Field) -> Self::Field;
fn set(thing: T, v: Self::Field) -> T {
Self::over(thing, |_| v)
}
}
impl<L, T> LensView<T> for Optics<L>
where
L: LensView<T>,
{
type Field = L::Field;
fn view(thing: T) -> Self::Field {
L::view(thing)
}
}
impl<L, T> LensOver<T> for Optics<L>
where
L: LensOver<T>,
{
fn over<F>(thing: T, f: F) -> T
where
F: FnOnce(Self::Field) -> Self::Field,
{
L::over(thing, f)
}
}
pub fn view<T, L: LensView<T>>(_lens: L, thing: T) -> L::Field {
L::view(thing)
}
pub fn set<T, L: LensOver<T>>(_lens: L, thing: T, v: L::Field) -> T {
L::set(thing, v)
}
pub fn over<T, L: LensOver<T>>(_lens: L, thing: T, f: impl FnOnce(L::Field) -> L::Field) -> T {
L::over(thing, f)
}

1
src/lenses/result.rs Normal file
View file

@ -0,0 +1 @@

View file

@ -1,9 +1,12 @@
use crate::{Lens, LensOver, LensTrait, LensView};
use crate::{
lenses::{LensOver, LensView},
Optics, OpticsTrait,
};
#[derive(Clone, Copy)]
pub struct _1Inner;
pub const _1: Lens<_1Inner> = Lens(_1Inner);
impl LensTrait for _1Inner {}
pub const _1: Optics<_1Inner> = Optics(_1Inner);
impl OpticsTrait for _1Inner {}
macro_rules! make_tuples {
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {

View file

@ -1,81 +1,30 @@
#![feature(unboxed_closures, fn_traits)]
/// Base trait
pub trait LensTrait {}
/// For lenses that allow viewing
pub trait LensView<T>: LensTrait {
type Field;
fn view(thing: T) -> Self::Field;
}
/// For lenses that allow setting
pub trait LensOver<T>: LensView<T> {
fn over<F>(thing: T, f: F) -> T
where
F: FnOnce(Self::Field) -> Self::Field;
fn set(thing: T, v: Self::Field) -> T {
Self::over(thing, |_| v)
}
}
/// Wrapper type
#[derive(Clone, Copy)]
pub struct Lens<T: LensTrait>(T);
impl<L: LensTrait> LensTrait for Lens<L> {}
impl<L, T> LensView<T> for Lens<L>
where
L: LensView<T>,
{
type Field = L::Field;
fn view(thing: T) -> Self::Field {
L::view(thing)
}
}
impl<L, T> LensOver<T> for Lens<L>
where
L: LensOver<T>,
{
fn over<F>(thing: T, f: F) -> T
where
F: FnOnce(Self::Field) -> Self::Field,
{
L::over(thing, f)
}
}
pub fn view<T, L: LensView<T>>(_lens: L, thing: T) -> L::Field {
L::view(thing)
}
pub fn set<T, L: LensOver<T>>(_lens: L, thing: T, v: L::Field) -> T {
L::set(thing, v)
}
pub fn over<T, L: LensOver<T>>(_lens: L, thing: T, f: impl FnOnce(L::Field) -> L::Field) -> T {
L::over(thing, f)
}
// TODO add third_from_tuple, etc
// TODO array traversals
// TODO something for structs
// TODO something for Ok, Some, etc
// TODO make over work with changing types
/// Base trait
pub trait OpticsTrait {}
/// Wrapper type
#[derive(Clone, Copy)]
pub struct Optics<T: OpticsTrait>(pub(crate) T);
impl<L: OpticsTrait> OpticsTrait for Optics<L> {}
mod combinations;
mod fns;
pub mod lenses;
#[cfg(test)]
mod tests {
use super::{
lenses::{_0, _1},
*,
};
use super::lenses::*;
#[test]
fn view_first_from_tuple() {