Skip to content

Instantly share code, notes, and snippets.

@emcake
Created August 25, 2017 11:11
Show Gist options
  • Save emcake/f85df38f583ce7939d8f3c1a1fdafd70 to your computer and use it in GitHub Desktop.
Save emcake/f85df38f583ce7939d8f3c1a1fdafd70 to your computer and use it in GitHub Desktop.
/*
To replicate:
type SuperArrow<'a, 'b> =
| Fn of (('a -> 'b) * string)
| Compose of SuperArrowCompose<'a,'b>
and SuperArrowCompose<'a,'b> =
abstract member eval : SuperArrowComposeEvaluator<'a, 'b, 'r> -> 'r
and SuperArrowComposeEvaluator<'a, 'b, 'r> =
abstract member apply<'c> : SuperArrow<'a, 'c> -> SuperArrow<'c, 'b> -> 'r
*/
//#[derive(Debug)]
struct MyFnWrapper<A,B> {
f : Box<Fn(A) -> B>,
n : String
}
impl<A,B> MyFnWrapper<A,B> {
pub fn new<F : 'static + Fn(A) -> B>(f:F, s:String) -> Self {
MyFnWrapper { f: Box::new(f), n: s }
}
}
trait SuperArrowComposeEval<A,B,R> {
fn apply<C>(&self, &SuperArrow<A,C>, &SuperArrow<C,B>) -> R;
}
trait SuperArrowCompose<A, B> {
fn eval<R,E:SuperArrowComposeEval<A, B, R>>(&self, &E) -> R;
}
struct SuperArrowComposeImpl<A,B,C> {
fnA : Box<SuperArrow<A,C>>,
fnB : Box<SuperArrow<C,B>>
}
impl<A,B,C> SuperArrowComposeImpl<A,B,C> {
fn new(fnA : SuperArrow<A,C>, fnB : SuperArrow<B,C>) {
SuperArrowComposeImpl {
fnA: Box::new(fnA),
fnB: Box::new(fnB)
}
}
}
impl<A,B,C> SuperArrowCompose<A,B> for SuperArrowComposeImpl<A,B,C> {
fn eval<R, E:SuperArrowComposeEval<A, B, R>>(&self, evaler:&E) -> R {
evaler.eval::<C>(self.fnA, self.fnB)
}
}
//#[derive(Debug)]
enum SuperArrow<A,B> {
Function(MyFnWrapper<A,B>),
Compose(Box<SuperArrowCompose<A,B>>),
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment