def functor_preserves_composition_of_morphisms(functor: Functor[A], f: Callable[[B], C], g: Callable[[A], B]) -> bool: return functor.fmap(compose(f, g)) == functor.fmap(g).fmap(f)
def map_replace(self, value: B) -> Functor[B]: """The <$ operator""" return compose(self.fmap, const)(value)
def lift_a_2(func: Callable[[A, B], C], fa: Ap[A], fb: Ap[B]) -> Ap[C]: """liftA2""" return compose(fb.amap, fa.fmap)(func)
def a_to_mb(some_a: A) -> Monad[B]: return compose(self.pure, func)(some_a)
def lift_a_1(func: Callable[[A], B], fa: Ap[A]) -> Ap[B]: return compose(fa.amap, Applicative.pure)(func)