[][src]Crate higher_cat

The Functor hierarchy using higher.

But Why?

This is just a proof of concept implementation of PureScript's functor hierarchy in Rust, and you should probably not use it extensively in your own code, not because it's buggy or unfinished but because it's not likely to produce very nice Rust code. I'm sorry, but this is Rust, it works differently from Haskell.

Nevertheless, if you ever wanted comonads and profunctors in Rust, you've got them.

What Is The Functor Hierarchy?

Honestly, if you didn't already learn this from Haskell or Scala or PureScript, put down the crate and back away. As mentioned above, you are much better off using Rusty idioms to write your code, and I would recommend learning about these concepts in the context of a language (such as Haskell) where they belong.

If you still want to learn about functors and applicatives and monads, I highly recommend the Category Theory for Programmers series.

Custom Derives

The higher-derive crate provides a custom derive for Functor:

#[derive(Lift, Functor, PartialEq, Debug)]
enum MyLittleOption<A> {
    Definitely(A),
    NotReally,
}

// The derive will map any variant field of type `A`:
let i = MyLittleOption::Definitely(123);
let o = i.map(|value: u8| value.to_string());
assert_eq!(MyLittleOption::Definitely("123".to_string()), o);

// And it will leave variants without an `A` in them alone:
let i = MyLittleOption::NotReally;
let o = i.map(|value: u8| value.to_string());
assert_eq!(MyLittleOption::NotReally, o);

Please note that this derive only maps types of A, and will not be able to work on types of eg. Vec<A>. You'll have to write your own Functor implementation for these.

Traits

Ap

Ap provides an implementation for Apply::apply using only Bind and Pure.

Applicative

An Applicative functor is anything which implements Functor, Apply and Pure.

Apply

Apply takes an F<Fn(A) -> B> and applies it to an F<A> to produce an F<B>.

Bifunctor

A Bifunctor lets you change the types of a generic type with two type parameters.

Bind

Bind lets you chain computations together.

Comonad

A Comonad is the opposite of a Monad, and also anything which implements Extend and Extract.

Contravariant

A Contravariant functor.

Extend

Extend is the opposite of Bind.

Extract

Extract lets you take a value of A out of an F<A>.

Functor

A Functor lets you change the type parameter of a generic type.

LiftM1

LiftM1 provides a default implementation for Functor::map using only Bind and Pure.

Monad

A Monad is like a burrito, and also anything which implements Bind and Applicative.

Monoid

A Monoid consists of a semigroup (the Add trait in Rust) and an empty value (the Default trait) plus the following laws:

Profunctor

A Profunctor is just a Bifunctor that is contravariant over its first argument and covariant over its second argument.

Pure

Pure lets you construct a value of type F<A> using a single value of A.