lubeck 0.0.0-prealpha.5-abandoned

Functional programming framework written in cutting edge rust
Documentation
use crate::prelude::GenType;

pub struct State<'a, S, A> {
    pub(crate) run_state: Option<Box<dyn FnOnce(S) -> (A, S) + 'a>>,
}

impl<'a, S, A> State<'a, S, A>
where
    S: Clone + 'a,
    A: 'a,
{
    pub fn new<F>(f: F) -> Self
    where
        F: FnOnce(S) -> (A, S) + 'a,
    {
        Self {
            run_state: Some(Box::new(f)),
        }
    }

    pub fn put(self, state: S) -> State<'a, S, ()> {
        State {
            run_state: Some(Box::new(move |_| ((), state))),
        }
    }

    pub fn get(self) -> State<'a, S, S> {
        let state_f = move |s| {
            let (_, s) = self.run(s);
            (s.clone(), s)
        };
        State {
            run_state: Some(Box::new(state_f)),
        }
    }

    pub fn modify<F>(self, f: F) -> Self
    where
        F: FnOnce(S) -> S + 'a,
    {
        let state_f = move |s| {
            let (a, s) = self.run(s);
            (a, f(s))
        };
        Self {
            run_state: Some(Box::new(state_f)),
        }
    }

    pub fn run(self, s: S) -> (A, S) {
        self.run_state
            .map(move |f| f(s))
            .expect("State has inner func")
    }
}

impl<'a, S, A> GenType for State<'a, S, A>
where
    S: Clone + 'a,
    A: 'a,
{
    type Type<B> = State<'a, S, B>;
}