refactor out modules to files
This commit is contained in:
parent
b14b3a4f29
commit
dcf7edf6a3
35
src/labelgen.rs
Normal file
35
src/labelgen.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
use crate::state::WithState;
|
||||||
|
|
||||||
|
// Generate a next label
|
||||||
|
pub trait States {
|
||||||
|
type Item;
|
||||||
|
fn init() -> Self::Item;
|
||||||
|
fn next<'c, Value>(f: impl FnOnce(Self::Item) -> Value + 'c) -> WithState<'c, Value, Self::Item>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IntCounter;
|
||||||
|
|
||||||
|
impl States for IntCounter
|
||||||
|
{
|
||||||
|
type Item = i32;
|
||||||
|
|
||||||
|
fn init() -> i32 { 0 }
|
||||||
|
|
||||||
|
fn next<'c, Value>(f: impl FnOnce(i32) -> Value + 'c) -> WithState<'c, Value, i32> {
|
||||||
|
WithState::of(move |n| { (f(n), n + 1) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct StrCat;
|
||||||
|
|
||||||
|
impl States for StrCat
|
||||||
|
{
|
||||||
|
type Item = String;
|
||||||
|
|
||||||
|
fn init() -> String { "a".to_string() }
|
||||||
|
|
||||||
|
fn next<'c, Value>(f: impl FnOnce(Self::Item) -> Value + 'c) -> WithState<'c, Value, Self::Item> {
|
||||||
|
WithState::of(move |n: String| { let s = n.clone(); (f(n), format!("{}a", s)) })
|
||||||
|
}
|
||||||
|
}
|
||||||
78
src/main.rs
78
src/main.rs
@ -1,79 +1,7 @@
|
|||||||
mod state {
|
mod state;
|
||||||
// State monad
|
mod labelgen;
|
||||||
pub struct WithState<'c, Value, State>(Box<dyn FnOnce(State) -> (Value, State) + 'c>);
|
|
||||||
|
|
||||||
impl <'c, Value, State> WithState<'c, Value, State> {
|
use labelgen::{IntCounter, States};
|
||||||
pub fn of(f: impl FnOnce(State) -> (Value, State) + 'c) -> WithState<'c, Value, State> {
|
|
||||||
WithState(Box::new(f))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(self, s: State) -> (Value, State) {
|
|
||||||
self.0(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bind<'cn, NewValue>(self, f: impl FnOnce(Value) -> WithState<'cn, NewValue, State> + 'cn) -> WithState<'cn, NewValue, State>
|
|
||||||
where 'c: 'cn, State : 'cn, Value : 'cn {
|
|
||||||
WithState::<'cn, NewValue, State>::of(move |n| {
|
|
||||||
let (x,sp) = self.run(n);
|
|
||||||
f(x).run(sp)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn zip<'cn, NewValue>(self, st: WithState<'cn, NewValue, State>) -> WithState<'cn, (Value,NewValue), State>
|
|
||||||
where 'c: 'cn, State: 'cn, Value: 'cn, NewValue: 'cn {
|
|
||||||
self.bind(|aa| st.map(|bb| (aa,bb)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map<'cn, NewValue>(self, f: impl FnOnce(Value) -> NewValue + 'cn) -> WithState<'cn, NewValue, State>
|
|
||||||
where 'c: 'cn, State : 'cn, Value : 'cn {
|
|
||||||
WithState::<'cn, NewValue, State>::of(move |n| {
|
|
||||||
let (x, sp) = self.run(n);
|
|
||||||
( f(x), sp )
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mod labelgenerators {
|
|
||||||
use super::state::WithState;
|
|
||||||
|
|
||||||
// Generate a next label
|
|
||||||
pub trait States {
|
|
||||||
type Item;
|
|
||||||
fn init() -> Self::Item;
|
|
||||||
fn next<'c, Value>(f: impl FnOnce(Self::Item) -> Value + 'c) -> WithState<'c, Value, Self::Item>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct IntCounter;
|
|
||||||
|
|
||||||
impl States for IntCounter
|
|
||||||
{
|
|
||||||
type Item = i32;
|
|
||||||
|
|
||||||
fn init() -> i32 { 0 }
|
|
||||||
|
|
||||||
fn next<'c, Value>(f: impl FnOnce(i32) -> Value + 'c) -> WithState<'c, Value, i32> {
|
|
||||||
WithState::of(move |n| { (f(n), n + 1) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub struct StrCat;
|
|
||||||
|
|
||||||
impl States for StrCat
|
|
||||||
{
|
|
||||||
type Item = String;
|
|
||||||
|
|
||||||
fn init() -> String { "a".to_string() }
|
|
||||||
|
|
||||||
fn next<'c, Value>(f: impl FnOnce(Self::Item) -> Value + 'c) -> WithState<'c, Value, Self::Item> {
|
|
||||||
WithState::of(move |n: String| { let s = n.clone(); (f(n), format!("{}a", s)) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
use labelgenerators::*;
|
|
||||||
use state::WithState;
|
use state::WithState;
|
||||||
|
|
||||||
// Tree
|
// Tree
|
||||||
|
|||||||
33
src/state.rs
Normal file
33
src/state.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// State monad
|
||||||
|
pub struct WithState<'c, Value, State>(Box<dyn FnOnce(State) -> (Value, State) + 'c>);
|
||||||
|
|
||||||
|
impl <'c, Value, State> WithState<'c, Value, State> {
|
||||||
|
pub fn of(f: impl FnOnce(State) -> (Value, State) + 'c) -> WithState<'c, Value, State> {
|
||||||
|
WithState(Box::new(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(self, s: State) -> (Value, State) {
|
||||||
|
self.0(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind<'cn, NewValue>(self, f: impl FnOnce(Value) -> WithState<'cn, NewValue, State> + 'cn) -> WithState<'cn, NewValue, State>
|
||||||
|
where 'c: 'cn, State : 'cn, Value : 'cn {
|
||||||
|
WithState::<'cn, NewValue, State>::of(move |n| {
|
||||||
|
let (x,sp) = self.run(n);
|
||||||
|
f(x).run(sp)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn zip<'cn, NewValue>(self, st: WithState<'cn, NewValue, State>) -> WithState<'cn, (Value,NewValue), State>
|
||||||
|
where 'c: 'cn, State: 'cn, Value: 'cn, NewValue: 'cn {
|
||||||
|
self.bind(|aa| st.map(|bb| (aa,bb)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map<'cn, NewValue>(self, f: impl FnOnce(Value) -> NewValue + 'cn) -> WithState<'cn, NewValue, State>
|
||||||
|
where 'c: 'cn, State : 'cn, Value : 'cn {
|
||||||
|
WithState::<'cn, NewValue, State>::of(move |n| {
|
||||||
|
let (x, sp) = self.run(n);
|
||||||
|
( f(x), sp )
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user