Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simple Scala-like for comprehension for rust
// Simple Scala-like for comprehension for rust
macro_rules! comp(
// base case, using "map"
(val $id:ident <- $expr:expr $(,if $cond:expr)* $(,let $assign_id:pat = $assign_val:expr)* ,yield $comp:expr) =>
(
($expr)$(.filtered(|&$id| $cond))*.map(|&$id| {
$(let $assign_id = $assign_val;)* $comp
}
)
);
// recurisve case, using "flat_map"
(val $id:ident <- $expr:expr $(,if $cond:expr)* $(,let $assign_id:pat = $assign_val:expr)*
$(, val $id_r:ident <- $expr_r:expr $(,if $cond_r:expr)* $(,let $assign_id_r:pat = $assign_val_r:expr)*)* ,yield $comp:expr) =>
(
($expr)$(.filtered(|&$id| $cond))*.flat_map(|&$id| {
$(let $assign_id = $assign_val;)*
comp!($(val $id_r <- $expr_r $(,if $cond_r)* $(,let $assign_id_r = $assign_val_r)*),* ,yield $comp)
})
)
)
fn main() {
struct Number {
value : int
}
let result = comp!(
val x <- [Number{value: 1}, Number{value: 2}, Number{value: 3}],
let Number{value:y} = x,
val z <- [6,7,8],
if z % 2 == 0,
yield (y,z)
);
println(result.to_str());
// prints [(1, 6), (1, 8), (2, 6), (2, 8), (3, 6), (3, 8)]
// Notes:
// syntax: (val <var> <- generator (,if cond)* (,let <pattern> = value)*)+
// Patterns are NOT supported in val * <- Generator
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment