Expand description
§higher
The functor hierarchy and other terrible ideas for Rust.
Yes, this gives you generalisable monads in Rust. No, they’re not very nice compared to Haskell,
because Rust’s functions aren’t quite as first class from the type system’s perspective as you might
like them to be, type constraints in trait implementations can be a serious headache when you want
to implement, say, Functor
for HashSet
, and the type system can be particularly obtuse at times
and need a lot of additional and extremely verbose guidance to get the type inference right, but
they exist now.
What you get from this:
- A set of fine grained traits (
Functor
,Pure
,Apply
,Bind
,Applicative
andMonad
) for functors, applicatives and monads, inspired by PureScript and Scala’s Cats. - Bifunctors, contravariant functors and profunctors, for completeness.
- The
run!
macro for Haskell style do notation. I’d have preferred to call itdo!
orfor!
but unfortunately those are reserved keywords, even for macros. - Derive macros for
Functor
andBifunctor
. - Semigroups and monoids, because Rust’s
Add
isn’t quite a semigroup soAdd + Default
isn’t quite a monoid. - Effect monads that wrap standard
Future
s and IO monads that wrap futures that can fail. - Most of
Foldable
, with the ambition of some ofTraversable
to follow. (It’s alwaystraverse
.) - Rings and algebras, just in case.
- Not necessarily a lot of good documentation, but like any good Haskell programmer you should be able to immediately infer every function’s purpose from its type signature.
§What are your intentions with this?
I wrote this for two reasons: first, to see if it was even possible, and second, as a shitpost with some extremely elaborate type signatures. If you think this is actually useful (and I’m mildly horrified to find that I’m starting to think it might be), you may wish to step up to help maintain it, because I doubt I’ll keep giving it much attention once the novelty wears off.
§Licence
Copyright 2019 Bodil Stokke
This software is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
§Code of Conduct
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
Modules§
- algebras
- applicative
- apply
- bifunctor
- bind
- contra
- effect
- foldable
- functor
- io
- monad
- monoid
- profunctor
- pure
- rings
- semigroup
Macros§
- run
- Monadic do notation.
Traits§
- Applicative
- An
Applicative
functor is anything which implementsFunctor
,Apply
andPure
. - Apply
Apply
takes anF<Fn(A) -> B>
(or, rather, anF<ApplyFn<'a,A, B>>
specifically) and applies it to anF<A>
to produce anF<B>
.- Bifunctor
- A
Bifunctor
lets you change the types of a generic type with two type parameters. - Bind
Bind
lets you chain computations together.- Contravariant
- A
Contravariant
functor. - Foldable
- Functor
- A
Functor
lets you change the type parameter of a generic type. - Monad
- A
Monad
is like a burrito, and also anything which implementsBind
andApplicative
. - Monoid
- A
Monoid
consists of aSemigroup
and an empty value (theDefault
trait) plus the following laws: - Profunctor
- A
Profunctor
is just aBifunctor
that is contravariant over its first argument and covariant over its second argument. What’s the problem? - Pure
Pure
lets you construct a value of typeF<A>
from a single value ofA
.- Semigroup
- A
Semigroup
is a type with an associative operation. In plain terms, this means you can take two values of this type and add them together into a different value of the same type. The most obvious example of this is addition of numbers:2 + 2 = 4
, another is string concatenation:"Hello " + "Joe" = "Hello Joe"
.