Skip to content

Instantly share code, notes, and snippets.

@d-plaindoux
Last active September 7, 2018 08:20
Show Gist options
  • Save d-plaindoux/38fd6c3c6ee27214408500c542707c9b to your computer and use it in GitHub Desktop.
Save d-plaindoux/38fd6c3c6ee27214408500c542707c9b to your computer and use it in GitHub Desktop.
Simple comprehension macro in Rust
#[macro_export]
macro_rules! comprehension {
(($expr:expr) | $id:ident <- ($range:expr) if $cond:expr) => {{
let mut result = Vec::default();
for $id in $range {
if $cond {
result.push($expr);
}
}
result
}};
(($expr:expr) | $id:ident <- ($range:expr)) => {{
comprehension![ ($expr) | $id <- ($range) if true ]
}}
}
// Test
#[test]
fn it_apply_comprehension() {
let result = comprehension![ (x+1) | x <- (1..=2) ];
assert_eq!(vec![2,3], result);
}
@d-plaindoux
Copy link
Author

d-plaindoux commented Sep 6, 2018

Yes it's really better and much more easier to understand. In addition it corresponds to the comprehension implementation in FP.

@loganmzz
Copy link

loganmzz commented Sep 7, 2018

Better, I have reversed if construction logic

#[macro_export]
macro_rules! comprehension {
    (($expr:expr) | $id:ident <- ($range:expr) if $cond:expr) => {{
        comprehension![ ($expr) | $id <- ($range.filter(|$id| $cond)) ]
    }};
    (($expr:expr) | $id:ident <- ($range:expr)) => {{
        $range.map(|$id| $expr)
    }}
}

It prevents warning about unused variable when no condition is provided.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment