pub struct HNil;
Expand description
Represents the right-most end of a heterogeneous list
Examples
let h = h_cons(1, HNil);
let h = h.head;
assert_eq!(h, 1);
Implementations§
source§impl HNil
impl HNil
sourcepub fn len(&self) -> usizewhere
HNil: HList,
pub fn len(&self) -> usizewhere HNil: HList,
Returns the length of a given HList
Examples
use frunk_core::hlist;
let h = hlist![1, "hi"];
assert_eq!(h.len(), 2);
sourcepub fn is_empty(&self) -> boolwhere
HNil: HList,
pub fn is_empty(&self) -> boolwhere HNil: HList,
Returns whether a given HList is empty
Examples
use frunk_core::hlist;
let h = hlist![];
assert!(h.is_empty());
sourcepub fn prepend<H>(self, h: H) -> HCons<H, HNil>where
HNil: HList,
pub fn prepend<H>(self, h: H) -> HCons<H, HNil>where HNil: HList,
Prepend an item to the current HList
Examples
use frunk_core::hlist;
let h1 = hlist![1, "hi"];
let h2 = h1.prepend(true);
let (a, (b, c)) = h2.into_tuple2();
assert_eq!(a, true);
assert_eq!(b, 1);
assert_eq!(c, "hi");
sourcepub fn sculpt<Ts, Indices>(
self
) -> (Ts, <HNil as Sculptor<Ts, Indices>>::Remainder)where
HNil: Sculptor<Ts, Indices>,
pub fn sculpt<Ts, Indices>( self ) -> (Ts, <HNil as Sculptor<Ts, Indices>>::Remainder)where HNil: Sculptor<Ts, Indices>,
Consume the current HList and return an HList with the requested shape.
sculpt
allows us to extract/reshape/sculpt the current HList into another shape,
provided that the requested shape’s types are are contained within the current HList.
The Indices
type parameter allows the compiler to figure out that Ts
and Self
can be morphed into each other.
Examples
use frunk_core::{hlist, HList};
let h = hlist![9000, "joe", 41f32, true];
let (reshaped, remainder): (HList![f32, i32, &str], _) = h.sculpt();
assert_eq!(reshaped, hlist![41f32, 9000, "joe"]);
assert_eq!(remainder, hlist![true]);
sourcepub fn into_reverse(self) -> <HNil as IntoReverse>::Outputwhere
HNil: IntoReverse,
pub fn into_reverse(self) -> <HNil as IntoReverse>::Outputwhere HNil: IntoReverse,
Reverse the HList.
Examples
use frunk_core::hlist;
assert_eq!(hlist![].into_reverse(), hlist![]);
assert_eq!(
hlist![1, "hello", true, 42f32].into_reverse(),
hlist![42f32, true, "hello", 1],
)
sourcepub fn to_ref<'a>(&'a self) -> <HNil as ToRef<'a>>::Outputwhere
HNil: ToRef<'a>,
pub fn to_ref<'a>(&'a self) -> <HNil as ToRef<'a>>::Outputwhere HNil: ToRef<'a>,
Return an HList where the contents are references to the original HList on which this method was called.
Examples
use frunk_core::hlist;
assert_eq!(hlist![].to_ref(), hlist![]);
assert_eq!(hlist![1, true].to_ref(), hlist![&1, &true]);
sourcepub fn to_mut<'a>(&'a mut self) -> <HNil as ToMut<'a>>::Outputwhere
HNil: ToMut<'a>,
pub fn to_mut<'a>(&'a mut self) -> <HNil as ToMut<'a>>::Outputwhere HNil: ToMut<'a>,
Return an HList
where the contents are mutable references
to the original HList
on which this method was called.
Examples
use frunk_core::hlist;
assert_eq!(hlist![].to_mut(), hlist![]);
assert_eq!(hlist![1, true].to_mut(), hlist![&mut 1, &mut true]);
sourcepub fn map<F>(self, mapper: F) -> <HNil as HMappable<F>>::Outputwhere
HNil: HMappable<F>,
pub fn map<F>(self, mapper: F) -> <HNil as HMappable<F>>::Outputwhere HNil: HMappable<F>,
Apply a function to each element of an HList.
This transforms some HList![A, B, C, ..., E]
into some
HList![T, U, V, ..., Z]
. A variety of types are supported
for the folder argument:
- An
hlist![]
of closures (one for each element). - A single closure (for mapping an HList that is homogenous).
- A single
Poly
.
Examples
use frunk::HNil;
use frunk_core::hlist;
assert_eq!(HNil.map(HNil), HNil);
let h = hlist![1, false, 42f32];
// Sadly we need to help the compiler understand the bool type in our mapper
let mapped = h.to_ref().map(hlist![
|&n| n + 1,
|b: &bool| !b,
|&f| f + 1f32]);
assert_eq!(mapped, hlist![2, true, 43f32]);
// There is also a value-consuming version that passes values to your functions
// instead of just references:
let mapped2 = h.map(hlist![
|n| n + 3,
|b: bool| !b,
|f| f + 8959f32]);
assert_eq!(mapped2, hlist![4, true, 9001f32]);
sourcepub fn zip<Other>(self, other: Other) -> <HNil as HZippable<Other>>::Zippedwhere
HNil: HZippable<Other>,
pub fn zip<Other>(self, other: Other) -> <HNil as HZippable<Other>>::Zippedwhere HNil: HZippable<Other>,
Zip two HLists together.
This zips a HList![A1, B1, ..., C1]
with a HList![A2, B2, ..., C2]
to make a HList![(A1, A2), (B1, B2), ..., (C1, C2)]
Example
use frunk::HNil;
use frunk_core::hlist;
assert_eq!(HNil.zip(HNil), HNil);
let h1 = hlist![1, false, 42f32];
let h2 = hlist![true, "foo", 2];
let zipped = h1.zip(h2);
assert_eq!(zipped, hlist![
(1, true),
(false, "foo"),
(42f32, 2),
]);
sourcepub fn foldl<Folder, Acc>(
self,
folder: Folder,
acc: Acc
) -> <HNil as HFoldLeftable<Folder, Acc>>::Outputwhere
HNil: HFoldLeftable<Folder, Acc>,
pub fn foldl<Folder, Acc>( self, folder: Folder, acc: Acc ) -> <HNil as HFoldLeftable<Folder, Acc>>::Outputwhere HNil: HFoldLeftable<Folder, Acc>,
Perform a left fold over an HList.
This transforms some HList![A, B, C, ..., E]
into a single
value by visiting all of the elements in left-to-right order.
A variety of types are supported for the mapper argument:
- An
hlist![]
of closures (one for each element). - A single closure (for folding an HList that is homogenous).
- A single
Poly
.
The accumulator can freely change type over the course of the call.
When called with a list of N
functions, an expanded form of the
implementation with type annotations might look something like this:
let acc: Acc0 = init_value;
let acc: Acc1 = f1(acc, x1);
let acc: Acc2 = f2(acc, x2);
let acc: Acc3 = f3(acc, x3);
...
let acc: AccN = fN(acc, xN);
acc
Examples
use frunk_core::hlist;
let nil = hlist![];
assert_eq!(nil.foldl(hlist![], 0), 0);
let h = hlist![1, false, 42f32];
let folded = h.to_ref().foldl(
hlist![
|acc, &i| i + acc,
|acc, b: &bool| if !b && acc > 42 { 9000f32 } else { 0f32 },
|acc, &f| f + acc
],
1
);
assert_eq!(42f32, folded);
// There is also a value-consuming version that passes values to your folding
// functions instead of just references:
let folded2 = h.foldl(
hlist![
|acc, i| i + acc,
|acc, b: bool| if !b && acc > 42 { 9000f32 } else { 0f32 },
|acc, f| f + acc
],
8918
);
assert_eq!(9042f32, folded2)
sourcepub fn foldr<Folder, Init>(
self,
folder: Folder,
init: Init
) -> <HNil as HFoldRightable<Folder, Init>>::Outputwhere
HNil: HFoldRightable<Folder, Init>,
pub fn foldr<Folder, Init>( self, folder: Folder, init: Init ) -> <HNil as HFoldRightable<Folder, Init>>::Outputwhere HNil: HFoldRightable<Folder, Init>,
Perform a right fold over an HList.
This transforms some HList![A, B, C, ..., E]
into a single
value by visiting all of the elements in reverse order.
A variety of types are supported for the mapper argument:
- An
hlist![]
of closures (one for each element). - A single closure (for folding an HList that is homogenous), taken by reference.
- A single
Poly
.
The accumulator can freely change type over the course of the call.
Comparison to foldl
While the order of element traversal in foldl
may seem more natural,
foldr
does have its use cases, in particular when it is used to build
something that reflects the structure of the original HList (such as
folding an HList of Option
s into an Option
of an HList).
An implementation of such a function using foldl
will tend to
reverse the list, while foldr
will tend to preserve its order.
The reason for this is because foldr
performs what is known as
“structural induction;” it can be understood as follows:
- Write out the HList in terms of
h_cons
andHNil
. - Substitute each
h_cons
with a function, and substituteHNil
withinit
the list:
h_cons(x1, h_cons(x2, h_cons(x3, ...h_cons(xN, HNil)...)))
becomes:
f1( x1, f2( x2, f3( x3, ... fN( xN, init)...)))
Examples
use frunk_core::hlist;
let nil = hlist![];
assert_eq!(nil.foldr(hlist![], 0), 0);
let h = hlist![1, false, 42f32];
let folded = h.foldr(
hlist![
|acc, i| i + acc,
|acc, b: bool| if !b && acc > 42f32 { 9000 } else { 0 },
|acc, f| f + acc
],
1f32
);
assert_eq!(9001, folded)
Trait Implementations§
source§impl<F, Acc> HFoldLeftable<F, Acc> for HNil
impl<F, Acc> HFoldLeftable<F, Acc> for HNil
source§impl<F, Init> HFoldRightable<F, Init> for HNil
impl<F, Init> HFoldRightable<F, Init> for HNil
source§impl<F, Init> HFoldRightableOwned<F, Init> for HNil
impl<F, Init> HFoldRightableOwned<F, Init> for HNil
fn real_foldr( self, f: F, i: Init ) -> (<HNil as HFoldRightable<F, Init>>::Output, F)
source§impl HList for HNil
impl HList for HNil
source§const LEN: usize = 0usize
const LEN: usize = 0usize
source§fn static_len() -> usize
fn static_len() -> usize
source§impl IntoReverse for HNil
impl IntoReverse for HNil
type Output = HNil
source§fn into_reverse(self) -> <HNil as IntoReverse>::Output
fn into_reverse(self) -> <HNil as IntoReverse>::Output
source§impl IntoUnlabelled for HNil
impl IntoUnlabelled for HNil
Implementation for HNil
type Output = HNil
source§fn into_unlabelled(self) -> <HNil as IntoUnlabelled>::Output
fn into_unlabelled(self) -> <HNil as IntoUnlabelled>::Output
source§impl IntoValueLabelled for HNil
impl IntoValueLabelled for HNil
type Output = HNil
source§fn into_value_labelled(self) -> <HNil as IntoValueLabelled>::Output
fn into_value_labelled(self) -> <HNil as IntoValueLabelled>::Output
source§impl Ord for HNil
impl Ord for HNil
source§impl PartialEq for HNil
impl PartialEq for HNil
source§impl PartialOrd for HNil
impl PartialOrd for HNil
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read moresource§impl<SourceHead, SourceTail> Transmogrifier<HNil, HNil> for HCons<SourceHead, SourceTail>
impl<SourceHead, SourceTail> Transmogrifier<HNil, HNil> for HCons<SourceHead, SourceTail>
Implementation of Transmogrifier
for when the Target
is empty and the Source
is non-empty.
source§fn transmogrify(self) -> HNil
fn transmogrify(self) -> HNil
source§impl Transmogrifier<HNil, HNil> for HNil
impl Transmogrifier<HNil, HNil> for HNil
Implementation of Transmogrifier
for when the Target
is empty and the Source
is empty.
source§fn transmogrify(self) -> HNil
fn transmogrify(self) -> HNil
impl Copy for HNil
impl Eq for HNil
impl StructuralEq for HNil
impl StructuralPartialEq for HNil
Auto Trait Implementations§
impl RefUnwindSafe for HNil
impl Send for HNil
impl Sync for HNil
impl Unpin for HNil
impl UnwindSafe for HNil
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<Choices> CoproductSubsetter<CNil, HNil> for Choices
impl<Choices> CoproductSubsetter<CNil, HNil> for Choices
source§impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Qwhere Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.source§impl<T> FmtForward for T
impl<T> FmtForward for T
source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where Self: Display,
self
to use its Display
implementation when
Debug
-formatted.source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere T: ?Sized,
source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere Self: Sized,
source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere R: 'a,
self
and passes that borrow into the pipe function. Read moresource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere R: 'a,
self
and passes that borrow into the pipe function. Read moresource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere Self: Borrow<B>, B: 'a + ?Sized, R: 'a,
source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R ) -> Rwhere Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,
source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere Self: AsRef<U>, U: 'a + ?Sized, R: 'a,
self
, then passes self.as_ref()
into the pipe function.source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere Self: AsMut<U>, U: 'a + ?Sized, R: 'a,
self
, then passes self.as_mut()
into the pipe
function.source§impl<T> Tap for T
impl<T> Tap for T
source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere Self: Borrow<B>, B: ?Sized,
Borrow<B>
of a value. Read moresource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere Self: BorrowMut<B>, B: ?Sized,
BorrowMut<B>
of a value. Read moresource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere Self: AsRef<R>, R: ?Sized,
AsRef<R>
view of a value. Read moresource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere Self: AsMut<R>, R: ?Sized,
AsMut<R>
view of a value. Read moresource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere Self: Deref<Target = T>, T: ?Sized,
Deref::Target
of a value. Read moresource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere Self: DerefMut<Target = T> + Deref, T: ?Sized,
Deref::Target
of a value. Read moresource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere Self: Borrow<B>, B: ?Sized,
.tap_borrow()
only in debug builds, and is erased in release
builds.source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere Self: BorrowMut<B>, B: ?Sized,
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere Self: AsRef<R>, R: ?Sized,
.tap_ref()
only in debug builds, and is erased in release
builds.source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere Self: AsMut<R>, R: ?Sized,
.tap_ref_mut()
only in debug builds, and is erased in release
builds.