Skip to content

Instantly share code, notes, and snippets.

@gsilvis
Created January 9, 2017 04:10
Show Gist options
  • Save gsilvis/b3f02c04070af0ba5a775ea90d848932 to your computer and use it in GitHub Desktop.
Save gsilvis/b3f02c04070af0ba5a775ea90d848932 to your computer and use it in GitHub Desktop.
Macros 'n' shit
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 )* } }
);
(bindy $p: pat =<< $e: expr ; $( $t: tt )*) => (
bind($e, move |$p| mdo! { $( $t )* } )
);
(bindy $p: ident : $ty: ty =<< $e: expr ; $( $t: tt )*) => (
bind($e, move |$p : $ty| mdo! { $( $t )* } )
);
(ign $e: expr ; $( $t: tt )*) => (
bind($e, move |_| mdo! { $( $t )* })
);
(when $e: expr ; $( $t: tt )*) => (
bind(if $e { ret(()) } else { mzero() }, move |_| mdo! { $( $t )* })
);
(for $p: pat in $e: expr => { $( $inner: tt )* } ; $( $t: tt )*) => (
bind($e.fold(mzero(), move |_, $p| mdo! { $( $inner )* }),
move |_| mdo! { $( $t )* })
);
(loop { $( $inner: tt )* } ; $( $t: tt )*) => (
bind([()].iter().cycle().fold(mzero(), move |_, _| mdo! { $( $inner )* }),
move |_| mdo! {$ ($t )* })
);
(ret $f: expr) => (
$f
)
}
fn bind<T, U, F: FnMut(T) -> Option<U>>(m: Option<T>, mut f: F) -> Option<U> {
match m {
Some(a) => f(a),
None => None
}
}
pub fn ret<T>(x: T) -> Option<T> {
Some(x)
}
pub fn mzero<T>() -> Option<T> {
None
}
fn main() {
println!("Hello, world!");
bluh();
}
fn bluh() -> () {
let n = mdo! {
bindy x =<< Some(4);
bindy y =<< Some(5);
let z: i32 = 2;
for &(a, b) in [(2,3), (4,5)].iter() => {
bindy c =<< Some(a + 3);
bindy q: i32 =<< Some(2);
loop {
bindy c: u32 =<< Some(5);
ret ret(5)
};
ret Some(c + b)
};
ret ret(x + y + z)
};
println!("{:?}", n);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment