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
use crate::plug::{Plug, Plug2, Unplug, Unplug2}; pub trait Functor: Unplug + Plug<<Self as Unplug>::A> { fn fmap<B, F>(self, f: F) -> <Self as Plug<B>>::Out where Self: Plug<B>, F: FnOnce(<Self as Unplug>::A) -> B; } pub trait Apply: Functor { fn ap<B, F>(self, f: <Self as Plug<F>>::Out) -> <Self as Plug<B>>::Out where Self: Plug<B> + Plug<F>, F: FnOnce(<Self as Unplug>::A) -> B; } pub trait Applicative: Apply { fn pure(value: <Self as Unplug>::A) -> Self; } pub trait Monad: Applicative { fn bind<B, F>(self, f: F) -> <Self as Plug<B>>::Out where Self: Plug<B>, F: FnOnce(<Self as Unplug>::A) -> <Self as Plug<B>>::Out; } pub trait Semigroup { fn combine(self, other: Self) -> Self; } pub trait Monoid: Semigroup { fn mempty() -> Self; } pub trait Foldable: Unplug + Plug<<Self as Unplug>::A> { fn fold_left<B, F>(self, init: B, f: F) -> B where F: FnOnce(B, <Self as Unplug>::A) -> B; } pub trait Traverse: Functor + Foldable { fn traverse<F, M, B>(self, f: F) -> <M as Plug<<Self as Plug<B>>::Out>>::Out where Self: Plug<B>, M: Plug<<Self as Plug<B>>::Out> + Plug<B> + Applicative, F: FnOnce(<Self as Unplug>::A) -> <M as Plug<B>>::Out; } pub trait Show { fn show(a: Self) -> String; } pub trait Contravariant: Unplug + Plug<<Self as Unplug>::A> { fn contramap<B, F>(self, f: F) -> <Self as Plug<B>>::Out where Self: Plug<B>, F: FnOnce(B) -> <Self as Unplug>::A; } pub trait Alternative: Applicative { fn empty() -> Self; fn combine(self, other: Self) -> Self; } pub trait Bifunctor: Unplug2 + Plug2<<Self as Unplug2>::A, <Self as Unplug2>::B> { fn bimap<C, D, F, G>(self, f: F, g: G) -> <Self as Plug2<C, D>>::Out where Self: Plug2<C, D>, F: FnOnce(<Self as Unplug2>::A) -> C, G: FnOnce(<Self as Unplug2>::B) -> D; }