-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds FuncMut and PolyMut, which parallel Func and Poly. #137
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,7 +57,7 @@ | |
//! ``` | ||
|
||
use indices::{Here, Suffixed, There}; | ||
use traits::{Func, IntoReverse, Poly, ToMut, ToRef}; | ||
use traits::{Func, FuncMut, IntoReverse, Poly, PolyMut, ToMut, ToRef}; | ||
|
||
use std::ops::Add; | ||
|
||
|
@@ -352,9 +352,10 @@ macro_rules! gen_inherent_methods { | |
/// | ||
/// * An `hlist![]` of closures (one for each element). | ||
/// * A single closure (for mapping an HList that is homogenous). | ||
/// * A single [`Poly`]. | ||
/// * A single [`Poly`] or [`PolyMut`]. | ||
/// | ||
/// [`Poly`]: ../traits/struct.Poly.html | ||
/// [`PolyMut`]: ../traits/struct.PolyMut.html | ||
/// | ||
/// # Examples | ||
/// | ||
|
@@ -908,6 +909,20 @@ where | |
} | ||
} | ||
|
||
impl<P, H, Tail> HMappable<PolyMut<P>> for HCons<H, Tail> | ||
where | ||
P: FuncMut<H>, | ||
Tail: HMappable<PolyMut<P>>, | ||
{ | ||
type Output = HCons<<P as FuncMut<H>>::Output, <Tail as HMappable<PolyMut<P>>>::Output>; | ||
fn map(self, mut poly: PolyMut<P>) -> Self::Output { | ||
HCons { | ||
head: poly.0.call(self.head), | ||
tail: self.tail.map(poly), | ||
} | ||
} | ||
} | ||
|
||
/// Trait for mapping over an HList | ||
/// | ||
/// This trait is part of the implementation of the inherent method | ||
|
@@ -943,12 +958,12 @@ impl<F> HMappable<F> for HNil { | |
|
||
impl<F, R, H, Tail> HMappable<F> for HCons<H, Tail> | ||
where | ||
F: Fn(H) -> R, | ||
F: FnMut(H) -> R, | ||
Tail: HMappable<F>, | ||
{ | ||
type Output = HCons<R, <Tail as HMappable<F>>::Output>; | ||
|
||
fn map(self, f: F) -> Self::Output { | ||
fn map(self, mut f: F) -> Self::Output { | ||
let HCons { head, tail } = self; | ||
HCons { | ||
head: f(head), | ||
|
@@ -1143,11 +1158,11 @@ where | |
impl<F, H, Tail, Acc> HFoldLeftable<F, Acc> for HCons<H, Tail> | ||
where | ||
Tail: HFoldLeftable<F, Acc>, | ||
F: Fn(Acc, H) -> Acc, | ||
F: FnMut(Acc, H) -> Acc, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a test for this |
||
{ | ||
type Output = <Tail as HFoldLeftable<F, Acc>>::Output; | ||
|
||
fn foldl(self, f: F, acc: Acc) -> Self::Output { | ||
fn foldl(self, mut f: F, acc: Acc) -> Self::Output { | ||
let HCons { head, tail } = self; | ||
let acc = f(acc, head); | ||
tail.foldl(f, acc) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,13 @@ pub trait IntoReverse { | |
#[derive(Debug, Copy, Clone, Default)] | ||
pub struct Poly<T>(pub T); | ||
|
||
/// A wrapper like [`Poly`] for [`FuncMut`]. | ||
/// | ||
/// [`FuncMut`]: trait.FuncMut.html | ||
/// [`Poly`]: trait.Poly.html | ||
#[derive(Debug, Copy, Clone, Default)] | ||
pub struct PolyMut<T>(pub T); | ||
|
||
/// This is a simple, user-implementable alternative to `Fn`. | ||
/// | ||
/// Might not be necessary if/when Fn(Once, Mut) traits are implementable | ||
|
@@ -74,3 +81,45 @@ pub trait Func<Input> { | |
/// use cases. | ||
fn call(i: Input) -> Self::Output; | ||
} | ||
|
||
/// This is a user-implementable alternative to `FnMut`. | ||
/// | ||
/// Not necessary if/when the FnMut trait is implementable in stable Rust. | ||
ExpHP marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// | ||
/// ``` | ||
/// # #[macro_use] | ||
/// # extern crate frunk; | ||
/// # use frunk::{FuncMut, PolyMut}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because some items are exported under multiple paths, I've been making it a point for doc examples to always show the intended paths for using stuff from Likewise for the |
||
/// # use std::fmt::{Debug, Write}; | ||
/// | ||
/// struct ConcatDebug<'a>(&'a mut String); | ||
/// | ||
/// impl<'a, T: Debug> FuncMut<T> for ConcatDebug<'a> { | ||
/// type Output = (); | ||
/// fn call(&mut self, t: T) { | ||
/// write!(self.0, "{:?}", t).unwrap(); | ||
/// } | ||
/// } | ||
/// | ||
/// fn main() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hide the There's some examples of how I would format an example like this in |
||
/// let mut string = String::new(); | ||
/// | ||
/// { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Really can't wait for NLL... |
||
/// let mut concatter = ConcatDebug(&mut string); | ||
/// let l = hlist![ | ||
/// 23, | ||
/// "foo", | ||
/// (1, "two", 3.0) | ||
/// ]; | ||
/// l.map(PolyMut(concatter)); | ||
/// } | ||
/// | ||
/// assert_eq!(string, r#"23"foo"(1, "two", 3.0)"#); | ||
/// } | ||
/// ``` | ||
pub trait FuncMut<Input> { | ||
type Output; | ||
|
||
/// Call the `FuncMut`. | ||
fn call(&mut self, i: Input) -> Self::Output; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a test for this