Make node trait consume self

This commit is contained in:
Dennis
2022-08-19 18:58:17 +02:00
committed by Keavon Chambers
parent 12b33da083
commit bdad7aca47
10 changed files with 286 additions and 188 deletions

View File

@@ -3,111 +3,124 @@ use core::ops::Add;
use crate::Node;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct AddNode;
impl<'n, L: Add<R, Output = O> + 'n, R, O: 'n> Node<'n, (L, R)> for AddNode {
impl<'n, L: Add<R, Output = O> + 'n, R, O: 'n> Node<(L, R)> for AddNode {
type Output = <L as Add<R>>::Output;
fn eval(&'n self, input: (L, R)) -> Self::Output {
fn eval(self, input: (L, R)) -> Self::Output {
input.0 + input.1
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CloneNode;
impl<'n, O: Clone> Node<'n, &'n O> for CloneNode {
impl<'n, O: Clone> Node<&'n O> for CloneNode {
type Output = O;
fn eval(&'n self, input: &'n O) -> Self::Output {
fn eval(self, input: &'n O) -> Self::Output {
input.clone()
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FstNode;
impl<'n, T: 'n, U> Node<'n, (T, U)> for FstNode {
impl<'n, T: 'n, U> Node<(T, U)> for FstNode {
type Output = T;
fn eval(&'n self, input: (T, U)) -> Self::Output {
fn eval(self, input: (T, U)) -> Self::Output {
let (a, _) = input;
a
}
}
impl<'n, T: 'n, U> Node<'n, &'n (T, U)> for FstNode {
impl<'n, T: 'n, U> Node<&'n (T, U)> for FstNode {
type Output = &'n T;
fn eval(&'n self, input: &'n (T, U)) -> Self::Output {
fn eval(self, input: &'n (T, U)) -> Self::Output {
let (a, _) = input;
a
}
}
/// Destructures a Tuple of two values and returns the first one
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SndNode;
impl<'n, T, U: 'n> Node<'n, (T, U)> for SndNode {
impl<'n, T, U: 'n> Node<(T, U)> for SndNode {
type Output = U;
fn eval(&'n self, input: (T, U)) -> Self::Output {
fn eval(self, input: (T, U)) -> Self::Output {
let (_, b) = input;
b
}
}
impl<'n, T, U: 'n> Node<'n, &'n (T, U)> for SndNode {
impl<'n, T, U: 'n> Node<&'n (T, U)> for SndNode {
type Output = &'n U;
fn eval(&'n self, input: &'n (T, U)) -> Self::Output {
fn eval(self, input: &'n (T, U)) -> Self::Output {
let (_, b) = input;
b
}
}
/// Destructures a Tuple of two values and returns them in reverse order
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SwapNode;
impl<'n, T: 'n, U: 'n> Node<'n, (T, U)> for SwapNode {
impl<'n, T: 'n, U: 'n> Node<(T, U)> for SwapNode {
type Output = (U, T);
fn eval(&'n self, input: (T, U)) -> Self::Output {
fn eval(self, input: (T, U)) -> Self::Output {
let (a, b) = input;
(b, a)
}
}
impl<'n, T, U: 'n> Node<'n, &'n (T, U)> for SwapNode {
impl<'n, T, U: 'n> Node<&'n (T, U)> for SwapNode {
type Output = (&'n U, &'n T);
fn eval(&'n self, input: &'n (T, U)) -> Self::Output {
fn eval(self, input: &'n (T, U)) -> Self::Output {
let (a, b) = input;
(b, a)
}
}
/// Return a tuple with two instances of the input argument
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DupNode;
impl<'n, T: Clone + 'n> Node<'n, T> for DupNode {
impl<'n, T: Clone + 'n> Node<T> for DupNode {
type Output = (T, T);
fn eval(&'n self, input: T) -> Self::Output {
fn eval(self, input: T) -> Self::Output {
(input.clone(), input) //TODO: use Copy/Clone implementation
}
}
/// Return the Input Argument
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct IdNode;
impl<'n, T: 'n> Node<'n, T> for IdNode {
impl<'n, T: 'n> Node<T> for IdNode {
type Output = T;
fn eval(&'n self, input: T) -> Self::Output {
fn eval(self, input: T) -> Self::Output {
input
}
}
pub struct MapResultNode<'n, MN: Node<'n, I>, I, E>(pub MN, pub PhantomData<&'n (I, E)>);
pub struct MapResultNode<MN, I, E>(pub MN, pub PhantomData<(I, E)>);
impl<'n, MN: Node<'n, I>, I, E> Node<'n, Result<I, E>> for MapResultNode<'n, MN, I, E> {
impl<MN: Node<I>, I, E> Node<Result<I, E>> for MapResultNode<MN, I, E> {
type Output = Result<MN::Output, E>;
fn eval(&'n self, input: Result<I, E>) -> Self::Output {
fn eval(self, input: Result<I, E>) -> Self::Output {
input.map(|x| self.0.eval(x))
}
}
impl<'n, MN: Node<I> + Copy, I, E> Node<Result<I, E>> for &'n MapResultNode<MN, I, E> {
type Output = Result<MN::Output, E>;
fn eval(self, input: Result<I, E>) -> Self::Output {
input.map(|x| (&self.0).eval(x))
}
}
impl<'n, MN: Node<'n, I>, I, E> MapResultNode<'n, MN, I, E> {
impl<MN, I, E> MapResultNode<MN, I, E> {
pub const fn new(mn: MN) -> Self {
Self(mn, PhantomData)
}
}
pub struct FlatMapResultNode<'n, MN: Node<'n, I>, I, E>(pub MN, pub PhantomData<&'n (I, E)>);
pub struct FlatMapResultNode<MN: Node<I>, I, E>(pub MN, pub PhantomData<(I, E)>);
impl<'n, MN: Node<'n, I, Output = Result<O, E>>, I, O: 'n, E: 'n> Node<'n, Result<I, E>> for FlatMapResultNode<'n, MN, I, E> {
impl<'n, MN: Node<I, Output = Result<O, E>>, I, O: 'n, E: 'n> Node<Result<I, E>> for FlatMapResultNode<MN, I, E> {
type Output = Result<O, E>;
fn eval(&'n self, input: Result<I, E>) -> Self::Output {
fn eval(self, input: Result<I, E>) -> Self::Output {
match input.map(|x| self.0.eval(x)) {
Ok(Ok(x)) => Ok(x),
Ok(Err(e)) => Err(e),
@@ -116,7 +129,7 @@ impl<'n, MN: Node<'n, I, Output = Result<O, E>>, I, O: 'n, E: 'n> Node<'n, Resul
}
}
impl<'n, MN: Node<'n, I>, I, E> FlatMapResultNode<'n, MN, I, E> {
impl<MN: Node<I>, I, E> FlatMapResultNode<MN, I, E> {
pub const fn new(mn: MN) -> Self {
Self(mn, PhantomData)
}
@@ -131,26 +144,26 @@ mod test {
pub fn dup_node() {
let value = ValueNode(4u32);
let dup = DupNode.after(value);
assert_eq!(dup.eval(()), (&4, &4));
assert_eq!(dup.eval(()), (4, 4));
}
#[test]
pub fn id_node() {
let value = IdNode.after(ValueNode(4u32));
assert_eq!(value.eval(()), &4);
assert_eq!(value.eval(()), 4);
}
#[test]
pub fn clone_node() {
let cloned = CloneNode.after(ValueNode(4u32));
let cloned = CloneNode.after(&ValueNode(4u32));
assert_eq!(cloned.eval(()), 4);
}
#[test]
pub fn fst_node() {
let fst = FstNode.after(ValueNode((4u32, "a")).clone());
let fst = FstNode.after(ValueNode((4u32, "a")));
assert_eq!(fst.eval(()), 4);
}
#[test]
pub fn snd_node() {
let fst = SndNode.after(ValueNode((4u32, "a")).clone());
let fst = SndNode.after(ValueNode((4u32, "a")));
assert_eq!(fst.eval(()), "a");
}
#[test]
@@ -164,8 +177,8 @@ mod test {
}
#[test]
pub fn foo() {
fn int(_: (), state: &u32) -> &u32 {
state
fn int(_: (), state: &u32) -> u32 {
*state
}
fn swap(input: (u32, u32)) -> (u32, u32) {
(input.1, input.0)
@@ -173,6 +186,7 @@ mod test {
let fnn = FnNode::new(&swap);
let fns = FnNodeWithState::new(int, 42u32);
assert_eq!(fnn.eval((1u32, 2u32)), (2, 1));
assert_eq!(fns.eval(()), &42);
let result: u32 = (&fns).eval(());
assert_eq!(result, 42);
}
}