Module frunk_core::coproduct
source · Expand description
Module that holds Coproduct data structures, traits, and implementations
Think of “Coproduct” as ad-hoc enums; allowing you to do something like this
// 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());
RunOr, 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());
RunEnums
- Phantom type for signature purposes only (has no value)
- 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
- Trait for instantiating a coproduct from an element
- Trait for extracting a value from a coproduct in an exhaustive way.
- Trait for converting a coproduct into another that can hold its variants.
- Trait for folding a coproduct into a single value.
- Trait for mapping over a coproduct’s variants.
- Trait for borrowing a coproduct element by type
- Trait for extracting a subset of the possible types in a coproduct.
- Trait for retrieving a coproduct element by type