<## Implementing the Either monad in Rust

And here you have it, the Either monad.

Here is the actual data structure for our Either monad

And now for the implementation

I've started to really enjoy writing Rust, I think having an advanced enough type system really helps mitigate errors and helps ensure that code is correct. I love Haskell for this exact reason, I truly believe that it helps developers ensure that code is correct.

Out of curiousity, I wanted to know If I could have something like the Either monad in Rust, turns out that I can!. The idea behind this is based off something called Lightweight Higher Kinded Types , I will possibly talk about this sometime later as I expand on this post. Additionally please visit fp-core.rs for more information. It is about 2am right now, so I want to get the code out of the way ASAP.

And here you have it, the Either monad.

pub trait HKT<A, B> {type URI;type Target;}

pub trait Functor<A, B>: HKT<A, B> {fn fmap<F>(self, f: F) -> <Self as HKT<A, B>>::Targetwhere F: FnOnce(A) -> B;}

pub trait Chain<A, B>: HKT<A, B> {fn chain<F>(self, f: F) -> <Self as HKT<A, B>>::Targetwhere F: FnOnce(A) -> <Self as HKT<A, B>>::Target;}

pub trait HKT3<A, B, C> {type Target2;}

trait Apply<A, F, B> : Functor<A, B> + HKT3<A, F, B>where F: FnOnce(A) -> B,{fn ap(self, f: <Self as HKT3<A, F, B>>::Target2) -><Self as HKT<A, B>>::Target;}

trait Pure<A>: HKT<A, A> {fn of(self) -> <Self as HKT<A, A>>::Target;}

Here is the actual data structure for our Either monad

pub enum Either<L, R> {Left(L),Right(R)}

And now for the implementation

impl<L, R> Either<L, R> {fn unwrap(self) -> R {match self {Either::Left(l) => panic!("left value"),Either::Right(r) => r}}}impl <C, A, B> HKT<A, B> for Either<C, A> {type URI = Self;type Target = Either<C, B>;}impl <C, A, B> Functor<A, B> for Either<C, A> {fn fmap<F>(self, f: F) -> <Self as HKT<A, B>>::Targetwhere F: FnOnce(A) -> B {match self {Either::Left(x) => Either::Left(x),Either::Right(x) => Either::Right(f(x))}}}impl<C, A, B> Chain<A, B> for Either<C, A> {fn chain<F>(self, f: F) -> Self::Targetwhere F: FnOnce(A) -> <Self as HKT<A, B>>::Target {match self {Either::Left(x) => Either::Left(x),Either::Right(x) => f(x)}}}impl <D, A, B, C> HKT3<A, B, C> for Either<D, A> {type Target2 = Either<D, B>;}impl<C, A, F, B> Apply<A, F, B> for Either<C, A>where F: FnOnce(A) -> B,{fn ap(self, f: Self::Target2) -> Self::Target {match self {Either::Left(l) => Either::Left(l),Either::Right(r) => f.fmap(|z| z(r))}}}