Skip to content

Commit

Permalink
Release 0.1.28 (lloydmeta#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
lloydmeta authored Apr 25, 2017
1 parent e36e120 commit cfb9ecf
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 64 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "frunk"
version = "0.1.27"
version = "0.1.28"
authors = ["Lloyd <[email protected]>"]
description = "Frunk provides developers with a number of functional programming tools like HList, Coproduct, Generic, LabelledGeneric, Validated, Monoid, Semigroup and friends."
license = "MIT"
Expand All @@ -24,4 +24,4 @@ version = "0.0.16"

[dev-dependencies.frunk_laws]
path = "laws"
version = "0.0.5"
version = "0.0.6"
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,16 +285,20 @@ use frunk::coproduct::*;
// Declare the types we want in our Coproduct
type I32Bool = Coprod!(i32, f32, bool);

let co1: I32Bool = into_coproduct(3);
let co1 = I32Bool::inject(3);
let get_from_1a: Option<&i32> = co1.get();
let get_from_1b: Option<&bool> = co1.get();
// This will fail at compile time because i8 is not in our Coproduct type
// let get_from_1b: Option<&i8> = co1.get();
assert_eq!(get_from_1a, Some(&3));

assert_eq!(get_from_1a, Some(&3));
// None because co1 does not contain a bool, it contains an i32
assert_eq!(get_from_1b, None);

// This will fail at compile time because i8 is not in our Coproduct type
let nope_get_from_1b: Option<&i8> = co1.get(); // <-- will fail
// It's also impossible to inject something into a coproduct that is of the wrong type
// (not contained in the coproduct type)
let nope_co = I32Bool::inject(42f32); // <-- will fail

// We can fold our Coproduct into a single value by handling all types in it
assert_eq!(
co1.fold(hlist![|i| format!("int {}", i),
Expand Down
6 changes: 3 additions & 3 deletions benches/labelled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ fn big_from_24fields(b: &mut Bencher) {
#[bench]
fn big_transform_from_25fields(b: &mut Bencher) {
b.iter(|| {
let j = BigStruct25FieldsReverse::transform_from(build_big_struct_25fields());
j
})
let j = BigStruct25FieldsReverse::transform_from(build_big_struct_25fields());
j
})
}

#[bench]
Expand Down
4 changes: 2 additions & 2 deletions laws/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "frunk_laws"
version = "0.0.5"
version = "0.0.6"
authors = ["Lloyd <[email protected]>"]
description = "frunk_laws contains laws for algebras declared in Frunk."
license = "MIT"
Expand All @@ -13,7 +13,7 @@ travis-ci = { repository = "lloydmeta/frunk" }

[dependencies.frunk]
path = ".."
version = "0.1.27"
version = "0.1.28"

[dependencies]
quickcheck = "0.3"
96 changes: 47 additions & 49 deletions src/coproduct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
//!
//! ```
//! # #[macro_use] extern crate frunk; use frunk::coproduct::*; fn main() {
//! // For simplicity, assign our Coproduct type to a type alias
//! // This is purely optional.
//! type I32Bool = Coprod!(i32, bool);
//! let co1: I32Bool = into_coproduct(3);
//! let co2: I32Bool = into_coproduct(true);
//! // Inject things into our Coproduct type
//! let co1 = I32Bool::inject(3);
//! let co2 = I32Bool::inject(true);
//!
//! // Getting stuff
//! let get_from_1a: Option<&i32> = co1.get();
Expand All @@ -33,9 +36,8 @@
//! # use frunk::hlist::*;
//! # use frunk::coproduct::*; fn main() {
//! # type I32Bool = Coprod!(i32, bool);
//! # let co1: I32Bool = into_coproduct(3);
//! # let co2: I32Bool = into_coproduct(true);
//!
//! # let co1 = I32Bool::inject(3);
//! # let co2 = I32Bool::inject(true);
//! // In the below, we use unimplemented!() to make it obvious hat we know what type of
//! // item is inside our coproducts co1 and co2 but in real life, you should be writing
//! // complete functions for all the cases when folding coproducts
Expand All @@ -62,14 +64,14 @@ use frunk_core::hlist::*;
/// of supporting any arbitrary number of types instead of just 2.
///
/// To consctruct a Coproduct, you would typically declare a type using the `Coprod!` type
/// macro and then use the `into_coproduct` method.
/// macro and then use the `inject` method.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate frunk; use frunk::coproduct::*; fn main() {
/// type I32Bool = Coprod!(i32, bool);
/// let co1: I32Bool = into_coproduct(3);
/// let co1 = I32Bool::inject(3);
/// let get_from_1a: Option<&i32> = co1.get();
/// let get_from_1b: Option<&bool> = co1.get();
/// assert_eq!(get_from_1a, Some(&3));
Expand Down Expand Up @@ -100,7 +102,7 @@ pub enum CNil {}
/// ```
/// # #[macro_use] extern crate frunk; use frunk::coproduct::*; fn main() {
/// type I32Bool = Coprod!(i32, bool);
/// let co1: I32Bool = into_coproduct(3);
/// let co1 = I32Bool::inject(3);
/// # }
/// ```
#[macro_export]
Expand Down Expand Up @@ -128,45 +130,37 @@ macro_rules! Coprod {
// Forward trailing comma variants -->
}

// <-- For turning something into a Coproduct
pub trait IntoCoproduct<InsertType, Index> {
fn into(to_insert: InsertType) -> Self;
}

impl<I, Tail> IntoCoproduct<I, Here> for Coproduct<I, Tail> {
fn into(to_insert: I) -> Self {
Coproduct::Inl(to_insert)
}
}

impl<Head, I, Tail, TailIndex> IntoCoproduct<I, There<TailIndex>> for Coproduct<Head, Tail>
where Tail: IntoCoproduct<I, TailIndex>
{
fn into(to_insert: I) -> Self {
let tail_inserted = <Tail as IntoCoproduct<I, TailIndex>>::into(to_insert);
Coproduct::Inr(tail_inserted)
}
}

/// Function for returning a Coproduct from a given type
///
/// # Example
/// Trait for injecting something into a coproduct
///
/// ```
/// # #[macro_use] extern crate frunk; use frunk::coproduct::*; fn main() {
/// type I32Bool = Coprod!(i32, f32);
/// let co1: I32Bool = into_coproduct(42f32);
/// let co1 = I32Bool::inject(42f32);
/// let get_from_1a: Option<&i32> = co1.get();
/// let get_from_1b: Option<&f32> = co1.get();
/// assert_eq!(get_from_1a, None);
/// assert_eq!(get_from_1b, Some(&42f32));
/// # }
/// ```
pub fn into_coproduct<C, I, Index>(to_into: I) -> C
where C: IntoCoproduct<I, Index>
pub trait CoprodInjector<InjectType, Index> {
fn inject(to_insert: InjectType) -> Self;
}

impl<I, Tail> CoprodInjector<I, Here> for Coproduct<I, Tail> {
fn inject(to_insert: I) -> Self {
Coproduct::Inl(to_insert)
}
}

impl<Head, I, Tail, TailIndex> CoprodInjector<I, There<TailIndex>> for Coproduct<Head, Tail>
where Tail: CoprodInjector<I, TailIndex>
{
<C as IntoCoproduct<I, Index>>::into(to_into)
fn inject(to_insert: I) -> Self {
let tail_inserted = <Tail as CoprodInjector<I, TailIndex>>::inject(to_insert);
Coproduct::Inr(tail_inserted)
}
}

// For turning something into a Coproduct -->

/// Trait for retrieving a coproduct element reference by type.
Expand All @@ -178,7 +172,9 @@ pub fn into_coproduct<C, I, Index>(to_into: I) -> C
/// ```
/// # #[macro_use] extern crate frunk; use frunk::coproduct::*; fn main() {
/// type I32Bool = Coprod!(i32, f32);
/// let co1: I32Bool = into_coproduct(42f32);
///
/// let co1 = I32Bool::inject(42f32);
///
/// let get_from_1a: Option<&i32> = co1.get();
/// let get_from_1b: Option<&f32> = co1.get();
/// assert_eq!(get_from_1a, None);
Expand Down Expand Up @@ -221,7 +217,9 @@ impl<Head, FromTail, Tail, TailIndex> CoproductSelector<FromTail, There<TailInde
/// ```
/// # #[macro_use] extern crate frunk; use frunk::coproduct::*; fn main() {
/// type I32Bool = Coprod!(i32, f32);
/// let co1: I32Bool = into_coproduct(42f32);
///
/// let co1 = I32Bool::inject(42f32);
///
/// let get_from_1a: Option<i32> = co1.take();
/// let get_from_1b: Option<f32> = co1.take();
/// assert_eq!(get_from_1a, None);
Expand Down Expand Up @@ -266,11 +264,11 @@ impl<Head, FromTail, Tail, TailIndex> CoproductTaker<FromTail, There<TailIndex>>
/// # #[macro_use] extern crate frunk;
/// # use frunk::coproduct::*;
/// # use frunk::hlist::*; fn main() {
/// type I32StrBool = Coprod!(i32, f32, bool);
/// type I32F32StrBool = Coprod!(i32, f32, bool);
///
/// let co1: I32StrBool = into_coproduct(3);
/// let co2: I32StrBool = into_coproduct(true);
/// let co3: I32StrBool = into_coproduct(42f32);
/// let co1 = I32F32StrBool::inject(3);
/// let co2 = I32F32StrBool::inject(true);
/// let co3 = I32F32StrBool::inject(42f32);
///
/// let folder = hlist![|&i| format!("int {}", i),
/// |&f| format!("float {}", f),
Expand Down Expand Up @@ -341,18 +339,18 @@ mod tests {
use super::Coproduct::*;

#[test]
fn test_into_coproduct() {
fn test_coproduct_inject() {
type I32StrBool = Coprod!(i32, &'static str, bool);

let co1: I32StrBool = into_coproduct(3);
let co1 = I32StrBool::inject(3);
assert_eq!(co1, Inl(3));
let get_from_1a: Option<&i32> = co1.get();
let get_from_1b: Option<&bool> = co1.get();
assert_eq!(get_from_1a, Some(&3));
assert_eq!(get_from_1b, None);


let co2: I32StrBool = into_coproduct(false);
let co2 = I32StrBool::inject(false);
assert_eq!(co2, Inr(Inr(Inl(false))));
let get_from_2a: Option<&i32> = co2.get();
let get_from_2b: Option<&bool> = co2.get();
Expand All @@ -362,9 +360,9 @@ mod tests {

#[test]
fn test_coproduct_fold_consuming() {
type I32StrBool = Coprod!(i32, f32, bool);
type I32F32StrBool = Coprod!(i32, f32, bool);

let co1: I32StrBool = into_coproduct(3);
let co1 = I32F32StrBool::inject(3);
let folded = co1.fold(hlist![|i| format!("int {}", i),
|f| format!("float {}", f),
|b| (if b { "t" } else { "f" }).to_string()]);
Expand All @@ -376,9 +374,9 @@ mod tests {
fn test_coproduct_fold_non_consuming() {
type I32StrBool = Coprod!(i32, f32, bool);

let co1: I32StrBool = into_coproduct(3);
let co2: I32StrBool = into_coproduct(true);
let co3: I32StrBool = into_coproduct(42f32);
let co1 = I32StrBool::inject(3);
let co2 = I32StrBool::inject(true);
let co3 = I32StrBool::inject(42f32);

assert_eq!(co1.as_ref()
.fold(hlist![|&i| format!("int {}", i),
Expand Down
8 changes: 4 additions & 4 deletions tests/coproduct_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ extern crate frunk_core; // for hlist macro
use frunk::coproduct::*;

#[test]
fn test_into_coproduct() {
fn test_inject_coproduct() {
type I32StrBool = Coprod!(i32, &'static str, bool);

let co1: I32StrBool = into_coproduct(3);
let co1 = I32StrBool::inject(3);
let get_from_1a: Option<&i32> = co1.get();
let get_from_1b: Option<&bool> = co1.get();
assert_eq!(get_from_1a, Some(&3));
Expand All @@ -19,7 +19,7 @@ fn test_into_coproduct() {
fn test_coproduct_fold_consuming() {
type I32StrBool = Coprod!(i32, f32, bool);

let co1: I32StrBool = into_coproduct(3);
let co1 = I32StrBool::inject(3);
let folded = co1.fold(hlist![|i| format!("int {}", i),
|f| format!("float {}", f),
|b| (if b { "t" } else { "f" }).to_string()]);
Expand All @@ -31,7 +31,7 @@ fn test_coproduct_fold_consuming() {
fn test_coproduct_fold_non_consuming() {
type I32StrBool = Coprod!(i32, f32, bool);

let co: I32StrBool = into_coproduct(true);;
let co = I32StrBool::inject(true);

assert_eq!(co.as_ref()
.fold(hlist![|&i| format!("int {}", i),
Expand Down

0 comments on commit cfb9ecf

Please sign in to comment.