https://github.com/andylokandy/comp-rs
Pure-macro Do notation and List-comprehension for Option, Result and Iterator.
https://github.com/andylokandy/comp-rs
do-notation list-comprehension macro rust-lang
Last synced: 6 months ago
JSON representation
Pure-macro Do notation and List-comprehension for Option, Result and Iterator.
- Host: GitHub
- URL: https://github.com/andylokandy/comp-rs
- Owner: andylokandy
- License: mit
- Created: 2017-02-19T16:21:21.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2019-10-26T18:27:12.000Z (about 6 years ago)
- Last Synced: 2025-06-15T04:17:51.474Z (7 months ago)
- Topics: do-notation, list-comprehension, macro, rust-lang
- Language: Rust
- Homepage:
- Size: 17.6 KB
- Stars: 52
- Watchers: 2
- Forks: 4
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# `comp-rs`
[](https://travis-ci.org/goandylok/comp-rs)
[](https://crates.io/crates/comp)
[](https://docs.rs/comp)
Pure-macro Do notation and List-comprehension for Option, Result and Iterator.
It provides syntax extensions to easily combind wrapper type (`Option`, `Result` and `Iterator`), which seems like
`for-comprehension` in scala or `Do notation` in haskell.
### [**Documentation**](https://docs.rs/comp/)
## Usage
First, add the following to your `Cargo.toml`:
```toml
[dependencies]
comp = "*"
```
Next, add this to your crate root:
```rust
#[macro_use]
extern crate comp;
```
## Example
`comp-rs` delivers three macros : *`option!`*, *`result!`* and *`iter!`*,
transforming the `arrow(<-)` statements into FP bind (`flat_map`).
### Iterator
```rust
#[macro_use]
extern crate comp;
let iter = iter! {
let x <- 0..2u8;
let y <- vec!['a', 'b'];
(x, y)
};
for x in iter {
println!("{:?}", x);
}
// Print (0, 'a') (0, 'b') (1, 'a') (1, 'b')
```
It can be written like generator expressions in python:
```python
# Python
values = [6, 2, 9, 4, -1, 33, 87, 23]
result = (x*x for x in values if x < 10)
```
or in scala
```scala
// Scala
val values = Array(6, 2, 9, 4, -1, 33, 87, 23)
val result = for(x <- values if x < 10) yield x*x
```
in Rust
```rust
// comp-rs
// The result is of type FlatMap and also lazy, like Python's generator expressions.
let values = vec![6, 2, 9, 4, -1, 33, 87, 23];
let result = iter!{let x <- values; if x < 10; x*x};
```
### Option
```rust
#[macro_use]
extern crate comp;
let option = option! {
let a <- Some(1);
let b <- Some(2);
a + b
};
assert_eq!(option, Some(3));
```
### Result
Unlike `Iterator` and `Option`, rust provides __*Question Mark*__ syntax to combine `Result`s.
Let's see how `comp-rs` makes it more explicit and expressive.
#### Native way
```rust
#[macro_use]
extern crate comp;
use std::fs::File;
use std::io;
use std::io::prelude::*;
// try!() macro must be wrap into a function
fn content() -> io::Result {
let mut f = try!(File::open("foo.txt"));
let mut s = String::new();
try!(f.read_to_string(&mut s));
Ok(s)
}
```
#### Question mark
```rust
#[macro_use]
extern crate comp;
use std::fs::File;
use std::io;
use std::io::prelude::*;
// '?' mark must be wrap into a function
fn content() -> io::Result {
let mut f = File::open("foo.txt")?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
}
```
#### `result!` way
```rust
#[macro_use]
extern crate comp;
use std::fs::File;
use std::io;
use std::io::prelude::*;
let content: io::Result = result! {
let mut f <- File::open("foo.txt");
let mut s = String::new();
let _ <- f.read_to_string(&mut s);
s
};
```
## Contribution
All kinds of contribution are welcome.
- **Issue** Feel free to open an issue when you find typos, bugs, or have any question.
- **Pull requests**. Better implementation, more tests, more documents and typo fixes are all welcome.
## License
Licensed under MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)