Skip to content

Instantly share code, notes, and snippets.

@anka-213
Forked from anonymous/playground.rs
Last active April 13, 2016 13:26
Show Gist options
  • Save anka-213/2a6ac95737eb13b2c26ddf76e0a0c0a4 to your computer and use it in GitHub Desktop.
Save anka-213/2a6ac95737eb13b2c26ddf76e0a0c0a4 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
#![feature(trace_macros)]
#![feature(log_syntax)]
//trace_macros!(true);
macro_rules! id {($e : expr) => ($e)}
macro_rules! vecc {($($t:tt)*) => (Vecc{v:vec!($($t)*)})}
macro_rules! mdo {
//{{$(let $pat : pat = $expr : expr;)+}; $($rest : tt)*} => ({let $pat = $expr; mdo!{$($rest)*}});
{{let $($rst : tt)+}; $($rest : tt)*} => (id!({let $($rst)+ mdo!{$($rest)*}}));
{$x : expr} => ($x);
//{$pat : pat = $b : expr; $x : expr} => ($b.and_then(|$pat| $x));
{ $pat : pat = $b : expr; $($b1 : tt)+} => ($b.and_then(|$pat| mdo!{$($b1)+ }))
}
//trait Unit[M<_>] { fn unit<T>(T) -> M<T>; }
#[derive(Debug)]
struct Vecc<T>{v: Vec<T>}
impl<T> Vecc<T> {
pub fn new() -> Vecc<T> {Vecc{v: Vec::new()}}
fn push(&mut self, value: T) {self.v.push(value)}
pub fn and_then<U, F: Fn(&T) -> Vecc<U>>(&self, f : F) -> Vecc<U> {
let mut out = Vecc::new();
for x in &self.v {
for y in f(x).v {
out.push(y);
}
}
out
}
}
fn main() {
fn sq(x: u32) -> Option<u32> { Some(x * x) }
fn nope(_: u32) -> Option<u32> { None }
let v : Vecc<(i32,i32)> = mdo!{a = vecc!(1,2); b = vecc!(3,4); vecc!((*a,*b))};
println!("{:?}", v);
let _ : Result<i32,i32> = mdo!{a = Ok(3); b = Ok(a); {println!("{}",a+b);Ok(b+a)}};
let _ : Option<u32> = mdo!{{let nn = Some(2);}; n = nn; m = sq(n); Some(m)};
assert_eq!(mdo!{n = Some(2); m = sq(n); sq(m)}, Some(16));
assert_eq!(mdo!{a = Some(2); a = sq(a); sq(a)}, Some(16));
assert_eq!(mdo!{a = Some(2); a = sq(a); nope(a)}, None);
assert_eq!(mdo!{a = Some(2); a = nope(a); sq(a)}, None);
assert_eq!(mdo!{a = None; a = sq(a); sq(a)}, None);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment