1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
use crate::{Cons, HList, Nil};
use super::Extend;
/// Flattens one level of nesting in a heterogenous list of heterogenous lists.
///
/// This is useful when you have a heterogenous list of heterogenous lists
/// and you want to remove one level of indirection.
pub trait Flatten: HList {
/// Flattened heterogenous list.
type Output: HList;
/// Flattens a heterogenous list of heterogenous lists, removing one level of indirection.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use hlist2::{hlist, ops::Flatten};
///
/// let data = hlist![hlist![1, 2.0, true, "hello world"], hlist![5, 6.0]];
/// let flattened = data.flatten();
/// assert_eq!(flattened, hlist![1, 2.0, true, "hello world", 5, 6.0]);
/// ```
///
/// Flattening only removes one level of nesting at a time:
///
/// ```
/// use hlist2::{hlist, ops::Flatten};
///
/// let d3 = hlist![
/// hlist![hlist![0, 1], hlist![2, 3]],
/// hlist![hlist![4, 5], hlist![6, 7]],
/// hlist![hlist![8, 9]],
/// ];
///
/// let d2 = d3.flatten();
/// assert_eq!(d2, hlist![hlist![0, 1], hlist![2, 3], hlist![4, 5], hlist![6, 7], hlist![8, 9]]);
///
/// let d1 = d3.flatten().flatten();
/// assert_eq!(d1, hlist![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
/// ```
///
/// Here we see that `flatten()` does not perform a “deep” flatten. Instead, only one level of nesting is removed.
/// That is, if you `flatten()` a three-dimensional array, the result will be two-dimensional and not one-dimensional.
/// To get a one-dimensional structure, you have to `flatten()` again.
fn flatten(self) -> Self::Output;
}
impl Flatten for Nil {
type Output = Self;
fn flatten(self) -> Self::Output {
self
}
}
impl<Head, Tail> Flatten for Cons<Head, Tail>
where
Head: Extend,
Tail: Flatten,
{
type Output = Head::Output<Tail::Output>;
fn flatten(self) -> Self::Output {
let Cons(head, tail) = self;
let tail = tail.flatten();
head.extend(tail)
}
}