higher_cat/lib.rs
1//! The `Functor` hierarchy using [`higher`][higher].
2//!
3//! # But Why?
4//!
5//! This is just a proof of concept implementation of PureScript's functor
6//! hierarchy in Rust, and you should probably not use it extensively in your
7//! own code, not because it's buggy or unfinished but because it's not likely
8//! to produce very nice Rust code. I'm sorry, but this is Rust, it works
9//! differently from Haskell.
10//!
11//! Nevertheless, if you ever wanted comonads and profunctors in Rust, you've
12//! got them.
13//!
14//! # What Is The Functor Hierarchy?
15//!
16//! Honestly, if you didn't already learn this from Haskell or Scala or
17//! PureScript, put down the crate and back away. As mentioned above, you are
18//! much better off using Rusty idioms to write your code, and I would recommend
19//! learning about these concepts in the context of a language (such as Haskell)
20//! where they belong.
21//!
22//! If you still want to learn about functors and applicatives and monads, I
23//! highly recommend the [Category Theory for Programmers][bartosz] series.
24//!
25//! # Custom Derives
26//!
27//! The [`higher-derive`][higher-derive] crate provides a custom derive for
28//! `Functor`:
29//!
30//! ```
31//! # use higher_derive::{Lift, Functor};
32//! # use higher::Lift;
33//! # use higher_cat::Functor;
34//! # fn main() {
35//! #[derive(Lift, Functor, PartialEq, Debug)]
36//! enum MyLittleOption<A> {
37//! Definitely(A),
38//! NotReally,
39//! }
40//!
41//! // The derive will map any variant field of type `A`:
42//! let i = MyLittleOption::Definitely(123);
43//! let o = i.map(|value: u8| value.to_string());
44//! assert_eq!(MyLittleOption::Definitely("123".to_string()), o);
45//!
46//! // And it will leave variants without an `A` in them alone:
47//! let i = MyLittleOption::NotReally;
48//! let o = i.map(|value: u8| value.to_string());
49//! assert_eq!(MyLittleOption::NotReally, o);
50//! # }
51//! ```
52//!
53//! Please note that this derive only maps types of `A`, and will not be able to
54//! work on types of eg. `Vec<A>`. You'll have to write your own `Functor`
55//! implementation for these.
56//!
57//! [higher]: https://docs.rs/crate/higher
58//! [higher-derive]: https://docs.rs/crate/higher-derive
59//! [bartosz]: https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/
60
61mod functor;
62pub use crate::functor::Functor;
63
64mod bifunctor;
65pub use crate::bifunctor::Bifunctor;
66
67mod profunctor;
68pub use crate::profunctor::Profunctor;
69
70mod apply;
71pub use crate::apply::Apply;
72
73mod pure;
74pub use crate::pure::Pure;
75
76mod applicative;
77pub use crate::applicative::Applicative;
78
79mod bind;
80pub use crate::bind::Bind;
81
82mod liftm1;
83pub use crate::liftm1::LiftM1;
84
85mod ap;
86pub use crate::ap::Ap;
87
88mod monad;
89pub use crate::monad::Monad;
90
91mod extend;
92pub use crate::extend::Extend;
93
94mod extract;
95pub use crate::extract::Extract;
96
97mod comonad;
98pub use crate::comonad::Comonad;
99
100mod contra;
101pub use crate::contra::Contravariant;
102
103mod monoid;
104pub use crate::monoid::Monoid;