class Functor f where
fmap :: (a -> b) -> f a -> f b
trait Functor<T> {
fn fmap<F, U>(Self<T>, f: F) -> Self<U>
where F: Fn(T) -> U;
}
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
trait Applicative<T>: Functor<T> {
fn pure(t: T) -> Self<T>;
fn chain<F, U>(Self<T>, f: F) -> Self<U>
where F: Self<Fn(T) -> U>;
}
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
trait Monad<T>: Applicative<T> {
fn bind<F, U>(Self<T>, F) -> Self<U>
where F: Fn(T) -> Self<U>;
}
class Semigroup a where
(<>) :: a -> a -> a infixr 6
trait SemiGroup<T> {
fn append(a: T, b: T): T
}
class Semigroup m => Monoid m where
mempty :: m
trait Monoid<T>: Semigroup<T> {
const zero: T;
}