Crate frunk[−][src]
Frunk: generic functional programming toolbelt for Rust
Aims to be a collection of functional programming abstractions implemented in Rust in effective, useful, and idiomatic ways. Examples of things that are included in rust are:
- HLists (heterogeneously-typed lists)
- LabelledGeneric, and Generic
- Coproduct
- Validated (accumulator for Result)
- Semigroup
- Monoid
Here is a small taste of what Frunk has to offer:
use frunk::prelude::*; use frunk::{self, monoid, Semigroup, Generic}; // Combining Monoids let v = vec![Some(1), Some(3)]; assert_eq!(monoid::combine_all(&v), Some(4)); // HLists let h = hlist![1, "hi"]; assert_eq!(h.len(), 2); let hlist_pat!(a, b) = h; assert_eq!(a, 1); assert_eq!(b, "hi"); let h1 = hlist![Some(1), 3.3, 53i64, "hello".to_owned()]; let h2 = hlist![Some(2), 1.2, 1i64, " world".to_owned()]; let h3 = hlist![Some(3), 4.5, 54, "hello world".to_owned()]; assert_eq!(h1.combine(&h2), h3); // Generic and LabelledGeneric-based programming // Allows Structs to play well easily with HLists #[derive(Generic, LabelledGeneric)] struct ApiUser<'a> { FirstName: &'a str, LastName: &'a str, Age: usize, } #[derive(Generic, LabelledGeneric)] struct NewUser<'a> { first_name: &'a str, last_name: &'a str, age: usize, } #[derive(LabelledGeneric)] struct SavedUser<'a> { first_name: &'a str, last_name: &'a str, age: usize, } // Instantiate a struct from an HList. Note that you can go the other way too. let a_user: ApiUser = frunk::from_generic(hlist!["Joe", "Blow", 30]); // Convert using Generic let n_user: NewUser = Generic::convert_from(a_user); // done // Convert using LabelledGeneric // // This will fail if the fields of the types converted to and from do not // have the same names or do not line up properly :) // // Also note that we're using a helper method to avoid having to use universal // function call syntax let s_user: SavedUser = frunk::labelled_convert_from(n_user); assert_eq!(s_user.first_name, "Joe"); assert_eq!(s_user.last_name, "Blow"); assert_eq!(s_user.age, 30); // Uh-oh ! last_name and first_name have been flipped! #[derive(LabelledGeneric)] struct DeletedUser<'a> { last_name: &'a str, first_name: &'a str, age: usize, } // let d_user = <DeletedUser as LabelledGeneric>::convert_from(s_user); <-- this would fail at compile time :) // This will, however, work, because we make use of the Sculptor type-class // to type-safely reshape the representations to align/match each other. let d_user: DeletedUser = frunk::transform_from(s_user); assert_eq!(d_user.first_name, "Joe");Run
Links:
Re-exports
pub use frunk_core::*; |
pub use frunk_derives::*; |
pub use hlist::HNil; |
pub use hlist::HCons; |
pub use hlist::lift_from; |
pub use traits::Poly; |
pub use traits::Func; |
pub use traits::ToRef; |
pub use coproduct::Coproduct; |
pub use generic::Generic; |
pub use generic::from_generic; |
pub use generic::into_generic; |
pub use generic::convert_from; |
pub use generic::map_repr; |
pub use generic::map_inter; |
pub use labelled::LabelledGeneric; |
pub use labelled::from_labelled_generic; |
pub use labelled::into_labelled_generic; |
pub use labelled::labelled_convert_from; |
pub use labelled::transform_from; |
pub use semigroup::Semigroup; |
pub use monoid::Monoid; |
pub use validated::Validated; |
Modules
monoid |
Module for holding Monoid typeclass definitions and default implementations |
prelude |
Traits that need to be imported for the complete |
semigroup |
Module for holding the Semigroup typeclass definition and typeclass instances |
validated |
Module for holding Validated logic |
Macros
Coprod |
Returns a type signature for a Coproduct of the provided types |
Hlist |
Returns a type signature for an HList of the provided types |
field |
Used for creating a Field |
hlist |
Returns an |
hlist_pat |
Macro for pattern-matching on HLists. |
poly_fn |
Returns a polymorphic function for use with mapping/folding heterogeneous types. |