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}