//! This file defines the Functor trait. //! //! This is the basis of the recursion scheme. //! //! More precisely, this file provides two versions of functor traits: //! one whose `map` function consumes `self`, and one whose `map` does //! not. /// A functor can map over its generic parameter. /// /// It can map from Functor(T) to Functor(S). pub trait Functor { /// The target of the map. /// /// Since Rust has no higher-kinded polymorphism, we have to /// express this type explicitly. /// /// # Note /// /// This is a generic associated type, so we need a minimal Rust /// version of 1.65, when this feature was first introduced to /// stable Rust. type Target: Functor; /// Map from Functor(T) to Functor(S). /// /// # Note /// /// This consumes `self`. If one wants not to consume `self`, /// then consider the trait [`FunctorRef`]. fn fmap(self, f: impl FnMut(T) -> S) -> Self::Target; } impl Functor for Vec { type Target = Vec; fn fmap(self, f: impl FnMut(T) -> S) -> Self::Target { self.into_iter().map(f).collect() } } /// A functor can map over its generic type parameter. /// /// It can map from Functor(T) to Functor(S). /// /// This is similar to [`Functor`], but the /// [`fmap`][FunctorRef::fmap_ref] method takes a reference and /// does not consume `self`. pub trait FunctorRef { /// The target of the map. /// /// Since Rust has no higher-kinded polymorphism, we have to /// express this type explicitly. /// /// # Note /// /// This is a generic associated type, so we need a minimal Rust /// version of 1.65, when this feature was first introduced to /// stable Rust. type Target: Functor; /// Map from Functor(T) to Functor(S). /// /// # Note /// /// This does notconsume `self`. If one wants to consume `self`, /// then consider the trait [`Functor`]. /// /// To avoid having to specify the trait when calling the method, /// we give it a distinct name. fn fmap_ref(&self, f: impl FnMut(T) -> S) -> Self::Target; }