diff --git a/src/func.rs b/src/func.rs
index ed483bc..c2cf7b4 100644
--- a/src/func.rs
+++ b/src/func.rs
@@ -10,6 +10,46 @@ pub trait WeakFunctor {
type F<'a, A>;
}
+/// Rust-specific implementation of [Functor], respecting `move` semantics.
+///
+/// Cannot insantiate for e.g. multi-element collections:
+/// ```compile_fail
+/// use radn_rs::func::*;
+///
+/// struct VecClass;
+///
+/// impl WeakFunctor for VecClass {
+/// type F<'a, A> = Vec;
+/// }
+///
+/// impl Functor for VecClass {
+/// fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> {
+/// fa.into_iter().map(f).collect()
+/// }
+/// }
+/// ```
+/// Why does it fail to compile? `.map` expects `FnMut` (or we can think of it being `Fn`, doesn't matter here). But what we provide it (`f`) is
+///
+/// For Haskell-style Functors, use [clone_func::CloneFunctor] instead.
+/// ```
+/// use radn_rs::func::clone_func::*;
+///
+/// struct VecClass;
+///
+/// impl CloneWeakFunctor for VecClass {
+/// type ClF<'a, A: Clone> = Vec;
+/// }
+///
+/// impl CloneFunctor for VecClass {
+/// fn clone_fmap<'a, A: 'a + Clone, B: 'a + Clone, F: 'a + Fn(A) -> B>(
+/// f: F,
+/// fa: Self::ClF<'a, A>,
+/// ) -> Self::ClF<'a, B> {
+/// fa.into_iter().map(f).collect()
+/// }
+/// }
+/// ```
+
pub trait Functor: WeakFunctor {
fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B>;
diff --git a/src/func/classes/optionclass.rs b/src/func/classes/optionclass.rs
index 56b4642..4e12b64 100644
--- a/src/func/classes/optionclass.rs
+++ b/src/func/classes/optionclass.rs
@@ -8,17 +8,11 @@ impl WeakFunctor for OptionClass {
impl Functor for OptionClass {
fn fmap<'a, A: 'a, B: 'a, F: 'a + FnOnce(A) -> B>(f: F, fa: Self::F<'a, A>) -> Self::F<'a, B> {
- match fa {
- Some(a) => Some(f(a)),
- None => None,
- }
+ fa.map(f)
}
fn replace<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, b: B) -> Self::F<'a, B> {
- match fa {
- Some(_) => Some(b),
- None => None,
- }
+ fa.map(|_| b)
}
}
diff --git a/src/func/classes/soloclass.rs b/src/func/classes/soloclass.rs
index 1a6c926..1075477 100644
--- a/src/func/classes/soloclass.rs
+++ b/src/func/classes/soloclass.rs
@@ -18,7 +18,6 @@ impl Functor for SoloClass {
fn void<'a, A: 'a>(fa: Self::F<'a, A>) -> Self::F<'a, ()> {
drop(fa);
- ()
}
}
diff --git a/src/func/clone_func.rs b/src/func/clone_func.rs
index 7131377..6048e07 100644
--- a/src/func/clone_func.rs
+++ b/src/func/clone_func.rs
@@ -67,7 +67,7 @@ pub trait CloneApplicativeSeq: CloneFunctor {
Self::clone_fmap(
move |a| {
let cf = f.clone();
- move |b: B| cf(a.clone(), b.clone())
+ move |b: B| cf(a.clone(), b)
},
fa,
),