Last active
July 10, 2017 02:42
-
-
Save KeenS/9665e098ade28fdcaf42bb77b9940c23 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// a parameterized monad | |
mod idx { | |
use std::marker::PhantomData; | |
#[derive(Debug)] | |
pub struct Idx<X, Y, A> | |
{ | |
x: A, | |
pre: PhantomData<X>, | |
post: PhantomData<Y>, | |
} | |
impl <X, Y, A>Idx<X, Y, A> | |
{ | |
pub fn new(a: A) -> Self { | |
Idx { | |
x: a, | |
pre: PhantomData, | |
post: PhantomData, | |
} | |
} | |
pub fn bind<Z, U, F>(&self, f: F) -> Idx<X, Z, U> | |
where F: Fn(&A) -> Idx<Y, Z, U>, | |
{ | |
let pre = self.pre; | |
let r = f(&self.x); | |
Idx{x:r.x, pre:pre, post:r.post} | |
} | |
} | |
impl <X, T>Idx<X, X, T> | |
{ | |
pub fn ret(x: T) -> Idx<X, X, T> { | |
Idx{x:x, pre:PhantomData, post:PhantomData} | |
} | |
} | |
impl <T>Idx<(), (), T> | |
{ | |
pub fn run(&self) -> &T { | |
&self.x | |
} | |
} | |
} | |
mod idx_sample { | |
use idx::Idx; | |
pub struct One; | |
pub struct Two; | |
pub fn op0to1<T>(x : T) -> Idx<(), One, T> { | |
Idx::new(x) | |
} | |
pub fn op1to2<T>(x : T) -> Idx<One, Two, T> { | |
Idx::new(x) | |
} | |
pub fn op2to0<T>(x : T) -> Idx<Two, (), T> { | |
Idx::new(x) | |
} | |
} | |
// https://github.com/TeXitoi/rust-mdo/blob/9b5f44e4159e4587afe14f5d3d99e475022b0959/src/lib.rs#L48-L90 | |
macro_rules! mdo { | |
( | |
let $p: pat = $e: expr ; $( $t: tt )* | |
) => ( | |
{ let $p = $e ; mdo! { $( $t )* } } | |
); | |
( | |
let $p: ident : $ty: ty = $e: expr ; $( $t: tt )* | |
) => ( | |
{ let $p: $ty = $e ; mdo! { $( $t )* } } | |
); | |
( | |
$p: pat =<< $e: expr ; $( $t: tt )* | |
) => ( | |
$e.bind(|$p| mdo! { $( $t )* } ) | |
); | |
( | |
$p: ident : $ty: ty =<< $e: expr ; $( $t: tt )* | |
) => ( | |
$e.bind(|$p : $ty| mdo! { $( $t )* } ) | |
); | |
( | |
ign $e: expr ; $( $t: tt )* | |
) => ( | |
$e.bind(|_| mdo! { $( $t )* }) | |
); | |
( | |
when $e: expr ; $( $t: tt )* | |
) => ( | |
(if $e { ret(()) } else { mzero() }).bind(|_| mdo! { $( $t )* }) | |
); | |
( | |
ret $f: expr | |
) => ( | |
$f | |
) | |
} | |
fn main() { | |
use idx::Idx; | |
use idx_sample::{op0to1, op1to2, op2to0}; | |
let m = || mdo! { | |
z =<< Idx::ret(10); | |
x =<< Idx::ret(20); | |
ret Idx::ret(z+x) | |
}; | |
println!("{:?}", m().run()); | |
let m2 = mdo! { | |
z =<< op0to1(123); | |
x =<< op1to2(345); | |
ign (op2to0(())); | |
ret Idx::ret(z * x) | |
}; | |
println!("{:?}", m2.run()); | |
let m3 = mdo! { | |
z =<< op0to1(123); | |
x =<< op1to2(345); | |
ign (op2to0(())); | |
ret Idx::ret(z * x * x) | |
}; | |
println!("{:?}", m3.run()); | |
// let m = mdo! { | |
// z =<< op0to1(123); | |
// x =<< op2to0(345); // ERROR | |
// ret Idx::ret(z * x) | |
// }; | |
// error[E0308]: mismatched types | |
// --> main.rs:137:15 | |
// | | |
// 135 | let m = mdo! { | |
// | - in this macro invocation | |
// 136 | z =<< op0to1(123); | |
// 137 | x =<< op2to0(345); // ERROR | |
// | ^^^^^^^^^^^ expected struct `idx::One`, found struct `idx::Two` | |
// | | |
// = note: expected type `idx::Idx<'_, idx::One, _, _>` | |
// = note: found type `idx::Idx<'_, idx::Two, (), {integer}>` | |
// error: aborting due to previous error | |
// let m3 = mdo! { | |
// z =<< op0to1(123); | |
// x =<< op1to2(345); | |
// ign m(); // ERROR: m is monomorphic | |
// ign (op2to0(())); | |
// ret Idx::ret(z * x) | |
// }; | |
// println!("{:?}", m2.run()); | |
// error[E0308]: mismatched types | |
// --> main.rs:111:13 | |
// | | |
// 108 | let m3 = mdo! { | |
// | - in this macro invocation | |
// ... | |
// 111 | ign m(); // ERROR: m is monomorphic | |
// | ^^^ expected struct `idx::Two`, found () | |
// | | |
// = note: expected type `idx::Idx<'_, idx::Two, _, _>` | |
// = note: found type `idx::Idx<'_, (), (), {integer}>` | |
// error: aborting due to previous error | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
see https://gist.github.com/keigoi/ff1d4352cfc158528db5ce539dfa41fd for original impl