fmap/
lib.rs

1//! Functors and monads in Rust
2//!
3//! *Note:* This crate has some limitations. Be sure to read the "Caveats"
4//! section below.
5//!
6//! # Functors
7//!
8//! The following traits are provided to describe functors:
9//!
10//! * [`Functor`] is a generic trait that provides an [`fmap`] method, which is
11//!   a generalization of [`Option::map`], [`Result::map`], and so on, and
12//!   which is [implemented] for a variety of types in the standard library.
13//! * [`FunctorSelf`] is a special case of `Functor` where types aren't changed
14//!   when mapping. It is automatically implemented through a blanket
15//!   implementation and it must be added as a bound when mapping a type to
16//!   itself.
17//! * [`FunctorMut`] is a special case of `FunctorSelf` whose [`fmap_mut`]
18//!   method operates on `&mut self`. It is not implemented automatically, but
19//!   this crate provides implementations for all types in the standard library
20//!   for which `Functor` is implemented.
21//!
22//! [`fmap`]: Functor::fmap
23//! [`fmap_mut`]: FunctorMut::fmap_mut
24//! [implemented]: Functor#foreign-impls
25//!
26//! # Contravariant functors
27//!
28//! The following traits are provided to describe contravariant functors, e.g.
29//! a `Writer<B>` that can be converted to a `Writer<A>` using an `Fn(A) -> B`.
30//!
31//! * [`Contravariant`] (akin to `Functor`)
32//! * [`ContravariantSelf`] (akin to `FunctorSelf`)
33//! * [`ContravariantMut`] (akin to `FunctorMut`)
34//!
35//! # Monads
36//!
37//! The [`Monad`] trait describes functors which are also monads. Its
38//! supertrait [`Pure`] allows wrapping a single value. ([`Pure::pure`] is
39//! equivalent to what's usually called "return" in the context of monads).
40//! Nested monads implement [`NestedMonad`] through a blanket implementation.
41//!
42//! # Applicative functors
43//!
44//! For applicative functors see the [`Applicative`] trait.
45//!
46//! # Caveats
47//!
48//! From the trait definitions in this crate, Rust can't always deduce type
49//! equality or deduce the implemented traits automatically. This may result in
50//! complex (possibly viral) type bounds being required, which may strongly
51//! **limit the usability of this crate.** Consider the following examples:
52//!
53//! ```
54//! # use fmap::Functor;
55//! fn foo1<'a, T>(functor: T) -> T
56//! where
57//!     T: Functor<'a, u16, Inner = u8>,
58//! {
59//!     functor.fmap(|x| x as u16).fmap(|x| x as u8) // works
60//! }
61//! ```
62//!
63//! ```compile_fail
64//! # use fmap::Functor;
65//! fn foo2<'a, T>(functor: T)
66//! where
67//!     T: Functor<'a, u16, Inner = u8>,
68//!     T: Functor<'a, u32, Inner = u16>,
69//! {
70//!     let _ = functor.fmap(|x| x as u16).fmap(|x| x as u32); // fails
71//! }
72//! ```
73//!
74//! ```
75//! # use fmap::Functor;
76//! fn foo3<'a, T>(functor: T)
77//! where
78//!     T: Functor<'a, u16, Inner = u8>,
79//!     T::Mapped: Functor<'a, u32, Inner = u16>, // this is needed instead
80//! {
81//!     let _ = functor.fmap(|x| x as u16).fmap(|x| x as u32);
82//! }
83//! ```
84//!
85//! Also see [`FunctorSelf`] for a workaround in the most simple cases.
86
87#![warn(missing_docs)]
88
89mod impls;
90#[cfg(test)]
91mod tests;
92
93/// A [`Functor`] that can be mapped to itself
94///
95/// This trait should be required as bound when the compiler shall infer that
96/// the return type of [`Functor::fmap`] is `Self`.
97///
98/// # Examples
99///
100/// ```
101/// # use fmap::FunctorSelf;
102/// fn double_inner_i32<'a, T>(outer: T) -> T
103/// where
104///     //T: Functor<'a, i32, Inner = i32>, // doesn't work
105///     T: FunctorSelf<'a, i32>, // use this instead
106/// {
107///     outer.fmap(|x| 2 * x)
108///     // NOTE: The following may be more efficient:
109///     // outer.fmap_fn_mutref(|x| *x *= 2)
110/// }
111/// ```
112pub trait FunctorSelf<'a, A>
113where
114    Self: Functor<'a, A, Inner = A, Mapped = Self>,
115    A: 'a,
116{
117}
118
119impl<'a, T, A> FunctorSelf<'a, A> for T
120where
121    T: Functor<'a, A, Inner = A, Mapped = Self>,
122    A: 'a,
123{
124}
125
126/// Generic type (e.g. `T<A>`) whose inner type can be mapped (e.g. resulting
127/// in `T<B>`)
128///
129/// Type parameter `B` specifies the new inner type *after* the [`fmap`]
130/// operation.
131///
132/// [`fmap`]: Self::fmap
133///
134/// # Examples
135///
136/// ## Implementing `Functor`
137///
138/// ```
139/// # use fmap::Functor;
140/// # struct Option<T>(T);
141/// # impl<T> Option<T> {
142/// #     pub fn map<U, F: FnOnce(T) -> U>(self, mut f: F) -> Option<U> {
143/// #         Option(f(self.0))
144/// #     }
145/// # }
146/// impl<'a, A, B> Functor<'a, B> for Option<A>
147/// where
148///     A: 'a,
149///     B: 'a,
150/// {
151///     type Inner = A;
152///     type Mapped = Option<B>;
153///     fn fmap<F>(self, f: F) -> Self::Mapped
154///     where
155///         F: 'a + Send + FnMut(Self::Inner) -> B,
156///     {
157///         self.map(f)
158///     }
159/// }
160/// ```
161///
162/// ### Using [`Functor::fmap`]
163///
164/// ```
165/// use fmap::Functor;
166///
167/// let ok: Result<i32, i32> = Ok(2);
168/// assert_eq!(ok.fmap(|x| x + 1), Ok(3));
169///
170/// let err: Result<i32, i32> = Err(0);
171/// assert_eq!(err.fmap(|x| x + 1), Err(0));
172///
173/// let int_vec: Vec<i32> = vec![2, 3, 5];
174/// let float_vec: Vec<f64> = int_vec.fmap(Into::into);
175/// assert_eq!(float_vec, vec![2.0, 3.0, 5.0]);
176///
177/// fn convert_inner<'a, T, A, B>(outer: T) -> T::Mapped
178/// where
179///     // NOTE: `A` and `B` can be different types. Where `A` and `B`
180///     // are always the same type, `FunctorSelf` should be used.
181///     T: Functor<'a, B, Inner = A>,
182///     A: 'a + Into<B>,
183/// {
184///     outer.fmap(Into::into)
185/// }
186///
187/// let int_vec2: Vec<i32> = vec![7, 11, 13];
188/// let float_vec2: Vec<f64> = convert_inner(int_vec2);
189/// assert_eq!(float_vec2, vec![7.0, 11.0, 13.0]);
190/// ```
191///
192/// Also see [`FunctorSelf`].
193pub trait Functor<'a, B>
194where
195    Self: Sized,
196    B: 'a,
197{
198    /// Inner type
199    ///
200    /// For any functor `T<A>`, where values of type `A` are passed to the
201    /// [`Functor::fmap`] function, set `Inner = A`.
202    type Inner: 'a;
203
204    /// `Self` but with [inner type] mapped to `B`
205    ///
206    /// For any functor `T`, define like:
207    /// `<T<A> as Functor<'a, B>>::Mapped = T<B>`.
208    ///
209    /// [inner type]: Functor::Inner
210    type Mapped: Functor<'a, B, Inner = B, Mapped = Self::Mapped>
211        + Functor<'a, Self::Inner, Inner = B, Mapped = Self>;
212
213    /// Replaces inner type and value by applying a mapping function
214    ///
215    /// Where [`Functor::Inner`] and `B` are the same type, consider using
216    /// [`Functor::fmap_fn_mutref`] or [`FunctorMut::fmap_mut`], which might
217    /// provide specialized implementations that are more efficient.
218    fn fmap<F>(self, f: F) -> Self::Mapped
219    where
220        F: 'a + Send + FnMut(Self::Inner) -> B;
221
222    /// Same as [`Functor::fmap`] but uses a mapping function that takes a
223    /// mutable reference
224    ///
225    /// This method has a default implementation that can be overridden if
226    /// there is a more efficient way of mapping inner values in place.
227    /// See also [`FunctorMut::fmap_mut`], which works on `&mut self`.
228    ///
229    /// For types which implement `FunctorMut` and where `fmap_mut`'s
230    /// implementation doesn't use `fmap_fn_mutref`, consider to provide the
231    /// following implementation:
232    ///
233    /// ```ignore
234    /// fn fmap_fn_mutref<F>(mut self, f: F) -> Self
235    /// where
236    ///     F: 'a + Send + FnMut(&mut Self::Inner),
237    /// {
238    ///     self.fmap_mut(f);
239    ///     self
240    /// }
241    /// ```
242    fn fmap_fn_mutref<F>(self, mut f: F) -> Self
243    where
244        Self: FunctorSelf<'a, B>,
245        F: 'a + Send + FnMut(&mut Self::Inner),
246    {
247        self.fmap(move |mut inner| {
248            f(&mut inner);
249            inner
250        })
251    }
252}
253
254/// Same as [`Functor`] but works on `&mut self`
255///
256/// This trait is not automatically implemented. If a type doesn't implement it
257/// but implements [`Functor`], you can always use the
258/// [`Functor::fmap_fn_mutref`] method, which has a default implementation.
259///
260/// # Examples
261///
262/// ```
263/// # use fmap::FunctorMut;
264/// fn double_inner_i32_in_place<'a, T>(outer: &mut T)
265/// where
266///     T: FunctorMut<'a, i32>,
267/// {
268///     outer.fmap_mut(|x| *x *= 2);
269/// }
270/// ```
271pub trait FunctorMut<'a, A>
272where
273    Self: FunctorSelf<'a, A>,
274    A: 'a,
275{
276    /// Same as [`Functor::fmap_fn_mutref`] but works on `&mut self`
277    fn fmap_mut<F>(&mut self, f: F)
278    where
279        F: 'a + Send + FnMut(&mut Self::Inner);
280}
281
282/// A [`Contravariant`] functor that can be mapped to itself
283///
284/// This trait should be required as bound when the compiler shall infer that
285/// the return type of [`Contravariant::contramap`] is `Self`.
286pub trait ContravariantSelf<'a, A>
287where
288    Self: Contravariant<'a, A, Inner = A, Mapped = Self>,
289    A: 'a,
290{
291}
292
293impl<'a, T, A> ContravariantSelf<'a, A> for T
294where
295    T: Contravariant<'a, A, Inner = A, Mapped = Self>,
296    A: 'a,
297{
298}
299
300/// Contravariant functor
301///
302/// # Examples
303///
304/// ```
305/// use fmap::Contravariant;
306///
307/// let mut output = String::new();
308/// {
309///     let mut string_printer: Box<dyn FnMut(String)> =
310///         Box::new(|s| {
311///             output.push_str(&s);
312///         });
313///     (string_printer)("Hello: ".to_string());
314///     let mut int_printer: Box<dyn FnMut(i32)> =
315///         string_printer.contramap(|n| format!("number {n}"));
316///     (int_printer)(13);
317/// }
318///
319/// assert_eq!(output, "Hello: number 13".to_string());
320/// ```
321pub trait Contravariant<'a, A>
322where
323    Self: Sized,
324    A: 'a,
325{
326    /// Inner type
327    ///
328    /// For any contravariant functor `T<B>`, where values of type `B` are
329    /// returned by the [`Contravariant::contramap`] function, set
330    /// `Inner = B`.
331    type Inner: 'a;
332
333    /// `Self` but consuming `A` instead of [`Contravariant::Inner`]
334    type Mapped: Contravariant<'a, A, Inner = A, Mapped = Self::Mapped>
335        + Contravariant<'a, Self::Inner, Inner = A, Mapped = Self>;
336
337    /// Returns an adapted version of `Self` with [`Contravariant::Inner`]
338    /// replaced
339    ///
340    /// This method uses an adaption function `f: FnMut(A) -> B` to replace
341    /// `Self::ContramapOut = B` with `A`.
342    fn contramap<F>(self, f: F) -> Self::Mapped
343    where
344        F: 'a + Send + FnMut(A) -> Self::Inner;
345
346    /// Same as [`Contravariant::contramap`] but uses a mapping function that
347    /// takes a mutable reference
348    fn contramap_fn_mutref<F>(self, mut f: F) -> Self
349    where
350        Self: ContravariantSelf<'a, A>,
351        F: 'a + Send + FnMut(&mut Self::Inner),
352    {
353        self.contramap(move |mut inner| {
354            f(&mut inner);
355            inner
356        })
357    }
358}
359
360/// Same as [`ContravariantSelf`] but works on `&mut self`
361pub trait ContravariantMut<'a, A>
362where
363    Self: ContravariantSelf<'a, A>,
364    A: 'a,
365{
366    /// Same as [`Contravariant::contramap_fn_mutref`] but works on `&mut self`
367    fn contramap_mut<F>(&mut self, f: F)
368    where
369        F: 'a + Send + FnMut(&mut Self::Inner);
370}
371
372/// A [`Functor`] that provides a [`pure`] operation to wrap a single inner
373/// value
374///
375/// Use this trait to implement a monad's "return" function.
376///
377/// [`pure`]: Self::pure
378///
379/// # Examples
380///
381/// ```
382/// use fmap::Pure;
383/// assert_eq!(Vec::<i32>::pure(6), vec![6]);
384/// ```
385pub trait Pure<'a, B>
386where
387    Self: Functor<'a, B>,
388    B: 'a,
389{
390    /// Wrap single value
391    ///
392    /// This is also called "return" in the context of monads.
393    fn pure(b: B) -> Self::Mapped;
394}
395
396/// A [`Functor`] that is also a monad
397///
398/// *Note:* The `Monad` trait deliberately does not imply `Applicative`.
399/// See documentation on [`Applicative`] for further information.
400///
401/// The method [`Monad::bind`] is a generalization of [`Option::and_then`] and
402/// [`Result::and_then`]. Pinned boxed [`Future`]s are also monads. The `bind`
403/// method will call the given closure on completion of the future. This monad
404/// implementation doesn't require [`Future::Output`] to be a [`Result`] and it
405/// will thus not short-circuit when a [`Result::Err`] is returned. Therefore,
406/// it rather behaves like `.then` (instead of `.and_then`) on futures.
407///
408/// Nested monads automatically implement [`NestedMonad`] and can be joined
409/// with [`NestedMonad::mjoin`], which is equivalent to `.bind(|x| x)`.
410///
411/// [`Future`]: std::future::Future
412/// [`Future::Output`]: std::future::Future::Output
413///
414/// # Examples
415///
416/// ```
417/// use fmap::Monad;
418///
419/// let a = vec![5, 6, 7];
420/// let b = a.bind(|x| vec![2*x, 10*x]);
421/// assert_eq!(b, vec![10, 50, 12, 60, 14, 70]);
422///
423/// let a: Box<dyn Iterator<Item = i32>> = Box::new(vec![5, 6, 7].into_iter());
424/// let b = a.bind(|x| Box::new(vec![2*x, 10*x].into_iter()));
425/// assert_eq!(b.collect::<Vec<_>>(), vec![10, 50, 12, 60, 14, 70]);
426///
427/// let nested = vec![vec![1, 3], vec![2, 9, 9]];
428/// assert_eq!(nested.bind(|x| x), vec![1, 3, 2, 9, 9]);
429/// ```
430///
431/// Note: `.bind(|x| x)` is also available as [`NestedMonad::mjoin`]
432pub trait Monad<'a, B>
433where
434    Self: Pure<'a, B>,
435    B: 'a,
436{
437    /// Call function with [inner values], returning [mapped] version of `Self`
438    ///
439    /// [inner values]: Functor::Inner
440    /// [mapped]: Functor::Mapped
441    fn bind<F>(self, f: F) -> Self::Mapped
442    where
443        F: 'a + Send + FnMut(Self::Inner) -> Self::Mapped;
444}
445
446/// Nested monad that can be [joined]
447///
448/// This trait is automatically implemented for nested monads with type
449/// parameter `A` being the inner monad.
450///
451/// [joined]: Self::mjoin
452///
453/// # Examples
454///
455/// ```
456/// use fmap::NestedMonad;
457///
458/// fn my_mjoin<'a, M: NestedMonad<'a, A>, A>(m: M) -> A
459/// where
460///     M: NestedMonad<'a, A>,
461///     A: 'a,
462/// {
463///     m.bind(|x| x)
464/// }
465///
466/// let nested = vec![vec![1, 3], vec![2, 9, 9]];
467/// assert_eq!(my_mjoin(nested.clone()), vec![1, 3, 2, 9, 9]);
468/// assert_eq!(nested.mjoin(), vec![1, 3, 2, 9, 9]);
469/// ```
470pub trait NestedMonad<'a, A>
471where
472    Self: Monad<'a, <Self::InnerMonad as Functor<'a, A>>::Inner>,
473    Self: Functor<
474        'a,
475        <Self::InnerMonad as Functor<'a, A>>::Inner,
476        Inner = A,
477        Mapped = A,
478    >,
479    A: 'a,
480{
481    /// Helper type always equal to `A`
482    ///
483    /// This type is needed to circumvent
484    /// [Rust issue #20671](https://github.com/rust-lang/rust/issues/20671).
485    type InnerMonad: Functor<'a, A>;
486    /// Generic join
487    ///
488    /// `.mjoin()` is equivalent to `.bind(|x| x)`.
489    fn mjoin(self) -> A {
490        self.bind(|x| x)
491    }
492}
493
494impl<'a, T, A> NestedMonad<'a, A> for T
495where
496    T: Monad<'a, <A as Functor<'a, A>>::Inner>,
497    A: Functor<'a, A>,
498    T: Functor<'a, <A as Functor<'a, A>>::Inner, Inner = A, Mapped = A>,
499    A: 'a,
500{
501    type InnerMonad = A;
502}
503
504/// Generic implementation of [`Functor::fmap`] for [`Monad`]s
505///
506/// This generic implementation can be used to define `Functor::fmap` based on
507/// [`Monad::bind`] and [`Pure::pure`] when the functor is also a monad. A more
508/// specific implementation might be more efficient though.
509pub fn monad_fmap<'a, T, B, F>(monad: T, mut f: F) -> T::Mapped
510where
511    T: Monad<'a, B>,
512    B: 'a,
513    F: 'a + Send + FnMut(T::Inner) -> B,
514{
515    monad.bind(move |inner| T::pure(f(inner)))
516}
517
518/// A [boxed] closure argument to [`<T as Functor<'a, B>>::fmap`], needed for
519/// [`Applicative`]
520///
521/// Closures must be boxed when being the [inner type] of an [`Applicative`]
522/// functor that is passed to [`Applicative::apply`].
523///
524/// [boxed]: Box
525/// [`<T as Functor<'a, B>>::fmap`]: Functor::fmap
526/// [inner type]: Functor::Inner
527pub type BoxMapper<'a, T, B> =
528    Box<dyn 'a + Send + FnMut(<T as Functor<'a, B>>::Inner) -> B>;
529
530/// An applicative [`Functor`]
531///
532/// *Note:* In functional programming, every monad is also an applicative
533/// functor. The [`Monad`] trait, however, does not have `Applicative` as
534/// superclass, because it is not possible to provide a corresponding
535/// `Applicative` implementation for every monad. The reason is that (unlike in
536/// functional programming) values in Rust may be moved and only used once. The
537/// `Applicative` implementation for `Vec<A>` demands `A: Clone`, for example,
538/// while the `Monad` implementation for `Vec<A>` does not put any bounds on
539/// `A`. The requirements for a monad to be able to implement
540/// [`Applicative::apply`] through [`monad_apply`] are:
541///
542/// * The monad must have a lifetime of `'a`.
543/// * The monad must be [`Send`].
544/// * The monad must be [`Clone`].
545/// * The monad must support a [boxed mapper] as [inner value] (which is the
546///   case when it implements the [`MonadWithMapper`] trait).
547///
548/// [boxed mapper]: BoxMapper
549/// [inner value]: Functor::Inner
550///
551/// # Examples
552///
553/// ```
554/// use fmap::Applicative;
555///
556/// let f: Vec<Box<dyn Send + FnMut(i32) -> i32>> =
557///     vec![Box::new(|x| x), Box::new(|x| x * 100)];
558/// let a = vec![4, 7, 9];
559/// let b = a.apply(f);
560/// assert_eq!(b, vec![4, 7, 9, 400, 700, 900]);
561/// ```
562pub trait Applicative<'a, B>
563where
564    Self: Pure<'a, B>,
565    Self: Pure<'a, BoxMapper<'a, Self, B>>,
566    B: 'a,
567{
568    /// Like [`Functor::fmap`], but takes a wrapped (and boxed) mapping
569    /// function
570    fn apply(
571        self,
572        f: <Self as Functor<'a, BoxMapper<'a, Self, B>>>::Mapped,
573    ) -> <Self as Functor<'a, B>>::Mapped;
574}
575
576/// Generic implementation of [`Functor::fmap`] for [`Applicative`] functors
577///
578/// This generic implementation can be used to define `Functor::fmap` based on
579/// [`Applicative::apply`] and [`Pure::pure`] when the functor is applicative.
580/// A more specific implementation might be more efficient though.
581pub fn applicative_fmap<'a, T, B, F>(
582    applicative: T,
583    f: F,
584) -> <T as Functor<'a, B>>::Mapped
585where
586    T: Applicative<'a, B>,
587    F: 'a + Send + FnMut(<T as Functor<'a, B>>::Inner) -> B,
588{
589    applicative.apply(T::pure(Box::new(f) as BoxMapper<'a, T, B>))
590}
591
592/// A [`Monad`] that can have a [boxed mapping closure] as an [inner value]
593///
594/// This trait is one of [`monad_apply`]'s bounds.
595///
596/// [boxed mapping closure]: BoxMapper
597/// [inner value]: Functor::Inner
598pub trait MonadWithMapper<'a, B>
599where
600    Self: Monad<'a, B>,
601    Self: Pure<'a, BoxMapper<'a, Self, B>>,
602    B: 'a,
603{
604    /// The [`Monad`] with the boxed mapping closure as [inner value]
605    ///
606    /// [inner value]: Functor::Inner
607    type MapperMonad: Functor<
608            'a,
609            B,
610            Inner = BoxMapper<'a, Self, B>,
611            Mapped = <Self as Functor<'a, B>>::Mapped,
612        > + Monad<'a, B>
613        + Pure<'a, BoxMapper<'a, Self, B>>;
614}
615
616impl<'a, T, B> MonadWithMapper<'a, B> for T
617where
618    T: Monad<'a, B>,
619    T: Pure<'a, BoxMapper<'a, T, B>>,
620    <T as Functor<'a, BoxMapper<'a, T, B>>>::Mapped: Functor<
621            'a,
622            B,
623            Inner = BoxMapper<'a, T, B>,
624            Mapped = <T as Functor<'a, B>>::Mapped,
625        > + Monad<'a, B>
626        + Pure<'a, BoxMapper<'a, T, B>>,
627    B: 'a,
628{
629    type MapperMonad = <T as Functor<'a, BoxMapper<'a, T, B>>>::Mapped;
630}
631
632/// Generic implementation of [`Applicative::apply`] for [`Monad`]s
633///
634/// This generic implementation can be used to define `Applicative::apply`
635/// based on [`Monad::bind`], [`Functor::fmap`], and [`Clone::clone`] when the
636/// applicative functor is also a monad and is `Send` and `Clone`. A more
637/// specific implementation might be more efficient.
638pub fn monad_apply<'a, T, B>(
639    monad: T,
640    f: T::MapperMonad,
641) -> <T as Functor<'a, B>>::Mapped
642where
643    T: 'a + Send + Clone,
644    T: MonadWithMapper<'a, B>,
645{
646    f.bind(move |inner| monad.clone().fmap(inner))
647}