### 22 releases (8 breaking)

0.8.3 | Jun 15, 2023 |
---|---|

0.7.0 | Jun 12, 2023 |

#**916** in Rust patterns

**986** downloads per month

**MIT/Apache**

60KB

1.5K
SLoC

# Functors (and Monads) in Rust

This crate provides functors and monads in Rust. The API is designed to
allow additional bounds on inner types, thus allowing implementation of
a common

trait for all collections in
`Functor`

,
including those which have an `std ::`collections

`Eq` `+` Hash

or an `Ord`

bound on their
relevant methods.Also included in this crate are

and `Functor`

implementations
for boxed iterators, futures, and functions.`Monad`

###
`lib.rs`

:

Functors and monads in Rust

*Note:* This crate has some limitations. Be sure to read the "Caveats"
section below.

# Functors

The following traits are provided to describe functors:

is a generic trait that provides an`Functor`

method, which is a generalization of`fmap`

,`Option`map`::`

, and so on, and which is implemented for a variety of types in the standard library.`Result`map`::`

is a special case of`FunctorSelf`

where types aren't changed when mapping. It is automatically implemented through a blanket implementation and it must be added as a bound when mapping a type to itself.`Functor`

is a special case of`FunctorMut`

whose`FunctorSelf`

method operates on`fmap_mut`

. It is not implemented automatically, but this crate provides implementations for all types in the standard library for which`&``mut``self`

is implemented.`Functor`

# Contravariant functors

The following traits are provided to describe contravariant functors, e.g.
a

that can be converted to a `Writer <B>`

`Writer``<`A`>`

using an `Fn``(`A`)` `->` B

.

(akin to`Contravariant`

)`Functor`

(akin to`ContravariantSelf`

)`FunctorSelf`

(akin to`ContravariantMut`

)`FunctorMut`

# Monads

The

trait describes functors which are also monads. Its
supertrait `Monad`

allows wrapping a single value. (`Pure`

is
equivalent to what's usually called "return" in the context of monads).
Nested monads implement `Pure ::`pure

`NestedMonad`

through a blanket implementation.# Applicative functors

For applicative functors see the

trait.`Applicative`

# Caveats

From the trait definitions in this crate, Rust can't always deduce type
equality or deduce the implemented traits automatically. This may result in
complex (possibly viral) type bounds being required, which may strongly
**limit the usability of this crate.** Consider the following examples:

`fn` `foo1``<``'a`, T`>``(``functor``:` T`)`` ``->` T
`where`
T`:` `Functor``<``'a`, `u16`, Inner = `u8``>`,
`{`
functor`.``fmap``(``|``x``|` `x ``as` `u16``)``.``fmap``(``|``x``|` `x ``as` `u8``)` `//` works
`}`

`fn` `foo2``<``'a`, T`>``(``functor``:` T`)``
``where`
T`:` `Functor``<``'a`, `u16`, Inner = `u8``>`,
T`:` `Functor``<``'a`, `u32`, Inner = `u16``>`,
`{`
`let` `_` `=` functor`.``fmap``(``|``x``|` `x ``as` `u16``)``.``fmap``(``|``x``|` `x ``as` `u32``)``;` `//` fails
`}`

`fn` `foo3``<``'a`, T`>``(``functor``:` T`)``
``where`
T`:` `Functor``<``'a`, `u16`, Inner = `u8``>`,
`T``::`Mapped`:` `Functor``<``'a`, `u32`, Inner = `u16``>`, `//` this is needed instead
`{`
`let` `_` `=` functor`.``fmap``(``|``x``|` `x ``as` `u16``)``.``fmap``(``|``x``|` `x ``as` `u32``)``;`
`}`

Also see

for a workaround in the most simple cases.`FunctorSelf`