pub enum Output<S, T> {
More(S),
Done(T),
}
impl<S, T> Output<S, T> {
pub fn more(self) -> S {
match self {
Output::More(s) => s,
Output::Done(_) => {
panic!("no more as computation done!");
}
}
}
pub fn done(self) -> T {
match self {
Output::More(_) => {
panic!("computation is not yet done!");
}
Output::Done(t) => t,
}
}
}
pub trait StepFn<S, T> {
fn step(&self, state: S) -> Output<S, T>;
fn nstep(&self, state: S, n: u64) -> Output<S, T> {
let mut st = state;
for _i in 0..n {
match self.step(st) {
Output::More(s) => {
st = s;
}
Output::Done(t) => {
return Output::Done(t);
}
}
}
Output::More(st)
}
fn bigstep(&self, state: S) -> T {
let mut st = state;
loop {
match self.step(st) {
Output::More(s) => {
st = s;
}
Output::Done(t) => {
return t;
}
}
}
}
}
pub trait StepMutFn<S, T> {
fn step(&mut self, state: S) -> Output<S, T>;
fn nstep(&mut self, state: S, n: u64) -> Output<S, T> {
let mut st = state;
for _i in 0..n {
match self.step(st) {
Output::More(s) => {
st = s;
}
Output::Done(t) => {
return Output::Done(t);
}
}
}
Output::More(st)
}
fn bigstep(&mut self, state: S) -> T {
let mut st = state;
loop {
match self.step(st) {
Output::More(s) => {
st = s;
}
Output::Done(t) => {
return t;
}
}
}
}
}