Stackless
covariant
This commit is contained in:
parent
d3c55ff1bd
commit
590cc0d6b2
@ -11,7 +11,7 @@ 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};
|
||||||
|
|
||||||
struct Wrapper<'a, F>(F, PhantomData<&'a ()>);
|
struct Wrapper<Q, F>(F, PhantomData<Q>);
|
||||||
|
|
||||||
trait Atom {
|
trait Atom {
|
||||||
fn next<'t>(self: Box<Self>) -> Oet<'t>
|
fn next<'t>(self: Box<Self>) -> Oet<'t>
|
||||||
@ -31,10 +31,7 @@ fn satom<'a, F: 'a + FnOnce() -> Oet<'a>>(f: F) -> Oet<'a> {
|
|||||||
Some(atom(f))
|
Some(atom(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, F> Atom for Wrapper<'a, F>
|
impl<'a, F: 'a + FnOnce() -> Oet<'a>> Atom for Wrapper<&'a (), F> {
|
||||||
where
|
|
||||||
F: 'a + FnOnce() -> Oet<'a>,
|
|
||||||
{
|
|
||||||
fn next<'t>(self: Box<Self>) -> Oet<'t>
|
fn next<'t>(self: Box<Self>) -> Oet<'t>
|
||||||
where
|
where
|
||||||
Self: 't,
|
Self: 't,
|
||||||
@ -67,7 +64,72 @@ impl<'a> EvalTree<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type StackessDyn<'a, A> = dyn 'a + FnOnce(Box<dyn 'a + FnOnce(A)>) -> Oet<'a>;
|
trait IntoOet<A> {
|
||||||
|
fn into_oet<'t>(self: Box<Self>, f: Box<dyn 't + FnOnce(A)>) -> Oet<'t>
|
||||||
|
where
|
||||||
|
Self: 't,
|
||||||
|
A: 't;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> Stackless<'a, B>> IntoOet<B>
|
||||||
|
for Wrapper<(&'a (), B), (Stackless<'a, A>, F)>
|
||||||
|
{
|
||||||
|
fn into_oet<'t>(self: Box<Self>, f: Box<dyn 't + FnOnce(B)>) -> Oet<'t>
|
||||||
|
where
|
||||||
|
Self: 't,
|
||||||
|
A: 't,
|
||||||
|
{
|
||||||
|
let cell_l = Rc::new(Cell::new(None));
|
||||||
|
let cell_r = cell_l.clone();
|
||||||
|
let (sstackless, sf) = self.0;
|
||||||
|
Some(EvalTree::Composite(
|
||||||
|
batom(move || sstackless.call(move |a| set_cell(cell_l, a))),
|
||||||
|
batom(move || {
|
||||||
|
let stackless = sf(get_cell(cell_r));
|
||||||
|
satom(|| stackless.0.into_oet(f))
|
||||||
|
}),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B> IntoOet<B>
|
||||||
|
for Wrapper<(&'a (), B, ()), (Stackless<'a, A>, F)>
|
||||||
|
{
|
||||||
|
fn into_oet<'t>(self: Box<Self>, f: Box<dyn 't + FnOnce(B)>) -> Oet<'t>
|
||||||
|
where
|
||||||
|
Self: 't,
|
||||||
|
A: 't,
|
||||||
|
{
|
||||||
|
let cell_l = Rc::new(Cell::new(None));
|
||||||
|
let cell_r = cell_l.clone();
|
||||||
|
let (sstackless, sf) = self.0;
|
||||||
|
Some(EvalTree::Composite(
|
||||||
|
batom(move || sstackless.call(move |a| set_cell(cell_l, a))),
|
||||||
|
batom(move || {
|
||||||
|
let b = sf(get_cell(cell_r));
|
||||||
|
satom(|| {
|
||||||
|
f(b);
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> IntoOet<A> for Wrapper<(), A> {
|
||||||
|
fn into_oet<'t>(self: Box<Self>, f: Box<dyn 't + FnOnce(A)>) -> Oet<'t>
|
||||||
|
where
|
||||||
|
Self: 't,
|
||||||
|
A: 't,
|
||||||
|
{
|
||||||
|
satom(|| {
|
||||||
|
f(self.0);
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type StackessDyn<'a, A> = dyn 'a + IntoOet<A>;
|
||||||
|
|
||||||
pub struct Stackless<'a, A: 'a>(Box<StackessDyn<'a, A>>);
|
pub struct Stackless<'a, A: 'a>(Box<StackessDyn<'a, A>>);
|
||||||
|
|
||||||
@ -86,41 +148,18 @@ fn get_cell<A>(cell: Rc<Cell<Option<A>>>) -> A {
|
|||||||
|
|
||||||
impl<'a, A: 'a> Stackless<'a, A> {
|
impl<'a, A: 'a> Stackless<'a, A> {
|
||||||
fn call(self, f: impl 'a + FnOnce(A)) -> Oet<'a> {
|
fn call(self, f: impl 'a + FnOnce(A)) -> Oet<'a> {
|
||||||
self.0(Box::new(f))
|
self.0.into_oet(Box::new(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Method-like equivalent of [`Monad::bind`],
|
/// Method-like equivalent of [`Monad::bind`],
|
||||||
/// the preferred way to chain [`Stackless<A>`] and `FnOnce(A) -> Stackless<B>` into [`Stackless<B>`].
|
/// the preferred way to chain [`Stackless<A>`] and `FnOnce(A) -> Stackless<B>` into [`Stackless<B>`].
|
||||||
pub fn bind<B: 'a>(self, f: impl 'a + FnOnce(A) -> Stackless<'a, B>) -> Stackless<'a, B> {
|
pub fn bind<B: 'a>(self, f: impl 'a + FnOnce(A) -> Stackless<'a, B>) -> Stackless<'a, B> {
|
||||||
Stackless(Box::new(|takesb| {
|
Stackless(Box::new(Wrapper((self, f), PhantomData)))
|
||||||
let cell_l = Rc::new(Cell::new(None));
|
|
||||||
let cell_r = cell_l.clone();
|
|
||||||
Some(EvalTree::Composite(
|
|
||||||
batom(move || self.call(move |a| set_cell(cell_l, a))),
|
|
||||||
batom(move || {
|
|
||||||
let stackless = f(get_cell(cell_r));
|
|
||||||
satom(|| stackless.0(takesb))
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Method-like equivalent of [`Functor::fmap`].
|
/// Method-like equivalent of [`Functor::fmap`].
|
||||||
pub fn map<B: 'a>(self, f: impl 'a + FnOnce(A) -> B) -> Stackless<'a, B> {
|
pub fn map<B: 'a>(self, f: impl 'a + FnOnce(A) -> B) -> Stackless<'a, B> {
|
||||||
Stackless(Box::new(|takesb| {
|
Stackless(Box::new(Wrapper((self, f), PhantomData)))
|
||||||
let cell_l = Rc::new(Cell::new(None));
|
|
||||||
let cell_r = cell_l.clone();
|
|
||||||
Some(EvalTree::Composite(
|
|
||||||
batom(move || self.call(move |a| set_cell(cell_l, a))),
|
|
||||||
batom(move || {
|
|
||||||
let b = f(get_cell(cell_r));
|
|
||||||
satom(|| {
|
|
||||||
takesb(b);
|
|
||||||
None
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate. Process is loop-like on the inside
|
/// Evaluate. Process is loop-like on the inside
|
||||||
@ -138,12 +177,7 @@ 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(Wrapper(value, PhantomData)))
|
||||||
satom(|| {
|
|
||||||
takesa(value);
|
|
||||||
None
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user