raskell
Haskell-style functional programming for Rust: combinators, type classes and types.
Implemented: hdo!, do notation over Option, Result and Vec, with an
async mode. See the roadmap for what is planned.
use hdo;
let result = hdo! ;
assert_eq!;
hdo! chains binds over Option, Result and Vec.
Statements
| Syntax | Meaning |
|---|---|
pattern <- expression; |
Bind. Short-circuits on None / Err, iterates over a Vec. |
pattern <-? expression; |
Bind a Result, converting the error through From. |
pattern <- expression throw error; |
Bind a Result whose pattern may fail to match. |
pattern: Type <- expression; |
Bind with the bound value's type spelled out. |
guard condition; |
Yield None (or drop the list element) unless condition holds. |
guard condition throw error; |
Yield Err(error) unless condition holds. |
let pattern[: Type] = expression; |
Plain let, no monad involved. |
expression; |
An action, sequenced like a bind whose value is discarded. |
pure expression |
Lifts a plain value into the block's monad. Must come last. |
expression |
A final expression without ;, already monadic. Must come last. |
A block has to end in a result: either pure value, which lifts a plain value,
or a final expression without a semicolon, which is already an Option,
Result or Vec and is returned as it is.
let lifted: = hdo! ;
let monadic: = hdo! ;
A last statement that keeps its ; is still an action, so the block is missing
its result and fails to compile.
Errors of different types
let result: = hdo! ;
Lists
let pairs: = hdo! ;
assert_eq!;
Async
Wrapping the statements in async { .. } expands the block into an async move
block, so .await works anywhere inside it. The result is a plain future:
.await it or spawn it.
let result: = hdo!
.await;
A final expression works there too, .await included:
let user: = hdo!
.await;
Futures are not awaited implicitly; write the .await yourself.
Limitations
- An
asyncblock bindsOptionandResultonly: a list bind cannot short-circuit a future. - Lists are bound as
Vec; other iterators need.collect()first.
See the crate documentation for the full reference.
Roadmap
Functions and combinators
map, filter, fold, compose, curry, flip, zip_with, maybe,
either.
Type classes, Rust-style
Functor, Applicative, Monad, Foldable, Traversable, Semigroup,
Monoid, as plain traits that compose with Iterator and the std traits.
Once Monad exists, hdo! should be defined in terms of it instead of the
per-type HdoBind impls it dispatches on today.
Types
Either, NonEmpty, later Reader, State, Writer.
License
MIT