stackless::atom
This commit is contained in:
parent
c2102268e4
commit
1959b1833e
@ -5,13 +5,46 @@
|
|||||||
//!
|
//!
|
||||||
//! [`lazy`]: super::lazy
|
//! [`lazy`]: super::lazy
|
||||||
|
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::{cell::Cell, rc::Rc};
|
use std::{cell::Cell, rc::Rc};
|
||||||
|
|
||||||
use crate::func::class_prelude::*;
|
use crate::func::class_prelude::*;
|
||||||
use crate::func::derivations::{ApplicativeLA2ViaSeq, ApplicativeTupleViaLA2};
|
use crate::func::derivations::{ApplicativeLA2ViaSeq, ApplicativeTupleViaLA2};
|
||||||
|
|
||||||
|
trait Atom {
|
||||||
|
fn next<'t>(self: Box<Self>) -> Oet<'t>
|
||||||
|
where
|
||||||
|
Self: 't;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Wrapper<'a, F>(F, PhantomData<&'a ()>);
|
||||||
|
|
||||||
|
fn atom<'a, F: 'a + FnOnce() -> Oet<'a>>(f: F) -> EvalTree<'a> {
|
||||||
|
EvalTree::Atom(Box::new(Wrapper(f, PhantomData)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn batom<'a, F: 'a + FnOnce() -> Oet<'a>>(f: F) -> Box<EvalTree<'a>> {
|
||||||
|
Box::new(atom(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn satom<'a, F: 'a + FnOnce() -> Oet<'a>>(f: F) -> Oet<'a> {
|
||||||
|
Some(atom(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, F> Atom for Wrapper<'a, F>
|
||||||
|
where
|
||||||
|
F: 'a + FnOnce() -> Oet<'a>,
|
||||||
|
{
|
||||||
|
fn next<'t>(self: Box<Self>) -> Oet<'t>
|
||||||
|
where
|
||||||
|
Self: 't,
|
||||||
|
{
|
||||||
|
(self.0)()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum EvalTree<'a> {
|
enum EvalTree<'a> {
|
||||||
Atom(Box<dyn 'a + FnOnce() -> Oet<'a>>),
|
Atom(Box<dyn 'a + Atom>),
|
||||||
Composite(Box<EvalTree<'a>>, Box<EvalTree<'a>>),
|
Composite(Box<EvalTree<'a>>, Box<EvalTree<'a>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,9 +53,9 @@ type Oet<'a> = Option<EvalTree<'a>>;
|
|||||||
impl<'a> EvalTree<'a> {
|
impl<'a> EvalTree<'a> {
|
||||||
fn next(self) -> Oet<'a> {
|
fn next(self) -> Oet<'a> {
|
||||||
match self {
|
match self {
|
||||||
Self::Atom(f) => f(),
|
Self::Atom(f) => f.next(),
|
||||||
Self::Composite(etl, etr) => match *etl {
|
Self::Composite(etl, etr) => match *etl {
|
||||||
Self::Atom(f) => match f() {
|
Self::Atom(f) => match f.next() {
|
||||||
Some(newleft) => Some(Self::Composite(Box::new(newleft), etr)),
|
Some(newleft) => Some(Self::Composite(Box::new(newleft), etr)),
|
||||||
None => Some(*etr),
|
None => Some(*etr),
|
||||||
},
|
},
|
||||||
@ -63,13 +96,11 @@ impl<'a, A: 'a> Stackless<'a, A> {
|
|||||||
let cell_l = Rc::new(Cell::new(None));
|
let cell_l = Rc::new(Cell::new(None));
|
||||||
let cell_r = cell_l.clone();
|
let cell_r = cell_l.clone();
|
||||||
Some(EvalTree::Composite(
|
Some(EvalTree::Composite(
|
||||||
Box::new(EvalTree::Atom(Box::new(move || {
|
batom(move || self.call(move |a| set_cell(cell_l, a))),
|
||||||
self.call(move |a| set_cell(cell_l, a))
|
batom(move || {
|
||||||
}))),
|
|
||||||
Box::new(EvalTree::Atom(Box::new(move || {
|
|
||||||
let stackless = f(get_cell(cell_r));
|
let stackless = f(get_cell(cell_r));
|
||||||
Some(EvalTree::Atom(Box::new(|| stackless.0(takesb))))
|
satom(|| stackless.0(takesb))
|
||||||
}))),
|
}),
|
||||||
))
|
))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -80,16 +111,14 @@ impl<'a, A: 'a> Stackless<'a, A> {
|
|||||||
let cell_l = Rc::new(Cell::new(None));
|
let cell_l = Rc::new(Cell::new(None));
|
||||||
let cell_r = cell_l.clone();
|
let cell_r = cell_l.clone();
|
||||||
Some(EvalTree::Composite(
|
Some(EvalTree::Composite(
|
||||||
Box::new(EvalTree::Atom(Box::new(move || {
|
batom(move || self.call(move |a| set_cell(cell_l, a))),
|
||||||
self.call(move |a| set_cell(cell_l, a))
|
batom(move || {
|
||||||
}))),
|
|
||||||
Box::new(EvalTree::Atom(Box::new(move || {
|
|
||||||
let b = f(get_cell(cell_r));
|
let b = f(get_cell(cell_r));
|
||||||
Some(EvalTree::Atom(Box::new(|| {
|
satom(|| {
|
||||||
takesb(b);
|
takesb(b);
|
||||||
None
|
None
|
||||||
})))
|
})
|
||||||
}))),
|
}),
|
||||||
))
|
))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -110,10 +139,10 @@ impl<'a, A: 'a> Stackless<'a, A> {
|
|||||||
impl<'a, A: 'a> From<A> for Stackless<'a, A> {
|
impl<'a, A: 'a> From<A> for Stackless<'a, A> {
|
||||||
fn from(value: A) -> Self {
|
fn from(value: A) -> Self {
|
||||||
Stackless(Box::new(|takesa| {
|
Stackless(Box::new(|takesa| {
|
||||||
Some(EvalTree::Atom(Box::new(|| {
|
satom(|| {
|
||||||
takesa(value);
|
takesa(value);
|
||||||
None
|
None
|
||||||
})))
|
})
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,11 +161,11 @@ impl<'a> Functor<'a> for StacklessInstance {
|
|||||||
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
|
fn replace<A: 'a, B: 'a>(fa: Self::F<A>, b: B) -> Self::F<B> {
|
||||||
Stackless(Box::new(|takesb| {
|
Stackless(Box::new(|takesb| {
|
||||||
Some(EvalTree::Composite(
|
Some(EvalTree::Composite(
|
||||||
Box::new(EvalTree::Atom(Box::new(move || fa.call(drop)))),
|
batom(move || fa.call(drop)),
|
||||||
Box::new(EvalTree::Atom(Box::new(move || {
|
batom(move || {
|
||||||
takesb(b);
|
takesb(b);
|
||||||
None
|
None
|
||||||
}))),
|
}),
|
||||||
))
|
))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -176,8 +205,8 @@ impl<'a> Applicative<'a> for StacklessInstance {
|
|||||||
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
|
fn discard_first<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<B> {
|
||||||
Stackless(Box::new(|takesb| {
|
Stackless(Box::new(|takesb| {
|
||||||
Some(EvalTree::Composite(
|
Some(EvalTree::Composite(
|
||||||
Box::new(EvalTree::Atom(Box::new(|| fa.call(drop)))),
|
batom(|| fa.call(drop)),
|
||||||
Box::new(EvalTree::Atom(Box::new(|| fb.0(takesb)))),
|
batom(|| fb.0(takesb)),
|
||||||
))
|
))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -185,8 +214,8 @@ impl<'a> Applicative<'a> for StacklessInstance {
|
|||||||
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
|
fn discard_second<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> Self::F<A> {
|
||||||
Stackless(Box::new(|takesa| {
|
Stackless(Box::new(|takesa| {
|
||||||
Some(EvalTree::Composite(
|
Some(EvalTree::Composite(
|
||||||
Box::new(EvalTree::Atom(Box::new(|| fa.0(takesa)))),
|
batom(|| fa.0(takesa)),
|
||||||
Box::new(EvalTree::Atom(Box::new(|| fb.call(drop)))),
|
batom(|| fb.call(drop)),
|
||||||
))
|
))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -211,13 +240,11 @@ impl<'a> Monad<'a> for StacklessInstance {
|
|||||||
let cell_l = Rc::new(Cell::new(None));
|
let cell_l = Rc::new(Cell::new(None));
|
||||||
let cell_r = cell_l.clone();
|
let cell_r = cell_l.clone();
|
||||||
Some(EvalTree::Composite(
|
Some(EvalTree::Composite(
|
||||||
Box::new(EvalTree::Atom(Box::new(move || {
|
batom(move || ffa.call(move |a| set_cell(cell_l, a))),
|
||||||
ffa.call(move |a| set_cell(cell_l, a))
|
batom(move || {
|
||||||
}))),
|
|
||||||
Box::new(EvalTree::Atom(Box::new(move || {
|
|
||||||
let stackless = get_cell(cell_r);
|
let stackless = get_cell(cell_r);
|
||||||
Some(EvalTree::Atom(Box::new(|| stackless.0(takesa))))
|
satom(|| stackless.0(takesa))
|
||||||
}))),
|
}),
|
||||||
))
|
))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user