1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
//! The `Functor` hierarchy using [`higher`][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][bartosz] series. //! //! # Custom Derives //! //! The [`higher-derive`][higher-derive] crate provides a custom derive for //! `Functor`: //! //! ``` //! # use higher_derive::{Lift, Functor}; //! # use higher::Lift; //! # use higher_cat::Functor; //! # fn main() { //! #[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. //! //! [higher]: https://docs.rs/crate/higher //! [higher-derive]: https://docs.rs/crate/higher-derive //! [bartosz]: https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/ mod functor; pub use crate::functor::Functor; mod bifunctor; pub use crate::bifunctor::Bifunctor; mod profunctor; pub use crate::profunctor::Profunctor; mod apply; pub use crate::apply::Apply; mod pure; pub use crate::pure::Pure; mod applicative; pub use crate::applicative::Applicative; mod bind; pub use crate::bind::Bind; mod liftm1; pub use crate::liftm1::LiftM1; mod ap; pub use crate::ap::Ap; mod monad; pub use crate::monad::Monad; mod extend; pub use crate::extend::Extend; mod extract; pub use crate::extract::Extract; mod comonad; pub use crate::comonad::Comonad; mod contra; pub use crate::contra::Contravariant; mod monoid; pub use crate::monoid::Monoid;