[−][src]Module frunk_core::coproduct
Module that holds Coproduct data structures, traits, and implementations
Think of "Coproduct" as ad-hoc enums; allowing you to do something like this
#[macro_use] extern crate frunk; // For simplicity, assign our Coproduct type to a type alias // This is purely optional. type I32Bool = Coprod!(i32, bool); // 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(); let get_from_1b: Option<&bool> = co1.get(); assert_eq!(get_from_1a, Some(&3)); assert_eq!(get_from_1b, None); let get_from_2a: Option<&i32> = co2.get(); let get_from_2b: Option<&bool> = co2.get(); assert_eq!(get_from_2a, None); assert_eq!(get_from_2b, Some(&true)); // *Taking* stuff (by value) let take_from_1a: Option<i32> = co1.take(); assert_eq!(take_from_1a, Some(3)); // Or with a Result let uninject_from_1a: Result<i32, _> = co1.uninject(); let uninject_from_1b: Result<bool, _> = co1.uninject(); assert_eq!(uninject_from_1a, Ok(3)); assert!(uninject_from_1b.is_err());Run
Or, if you want to "fold" over all possible values of a coproduct
// In the below, we use unreachable!() 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 // // to_ref borrows every item so that we can fold without consuming the coproduct. assert_eq!( co1.to_ref().fold(hlist![|&i| format!("i32 {}", i), |&b| unreachable!() /* we know this won't happen for co1 */ ]), "i32 3".to_string()); assert_eq!( co2.to_ref().fold(hlist![|&i| unreachable!() /* we know this won't happen for co2 */, |&b| String::from(if b { "t" } else { "f" })]), "t".to_string()); // Here, we use the poly_fn! macro to declare a polymorphic function to avoid caring // about the order in which declare handlers for the types in our coproduct let folded = co1.fold( poly_fn![ |_b: bool| -> String { unreachable!() }, /* we know this won't happen for co1 */ |i: i32 | -> String { format!("i32 {}", i) }, ] ); assert_eq!(folded, "i32 3".to_string());Run
Enums
CNil | Phantom type for signature purposes only (has no value) |
Coproduct | Enum type representing a Coproduct. Think of this as a Result, but capable of supporting any arbitrary number of types instead of just 2. |
Traits
CoprodInjector | Trait for instantiating a coproduct from an element |
CoprodUninjector | Trait for extracting a value from a coproduct in an exhaustive way. |
CoproductEmbedder | Trait for converting a coproduct into another that can hold its variants. |
CoproductFoldable | Trait for folding a coproduct into a single value. |
CoproductSelector | Trait for borrowing a coproduct element by type |
CoproductSubsetter | Trait for extracting a subset of the possible types in a coproduct. |
CoproductTaker | Trait for retrieving a coproduct element by type |