<NME> fn.py
<BEF> from functools import reduce

from typing import Tuple, Callable, Any, TypeVar, overload  # noqa

A = TypeVar("A")
B = TypeVar("B")
C = TypeVar("C")
D = TypeVar("D")
E = TypeVar("E")
F = TypeVar("F")
G = TypeVar("G")


@overload
def compose() -> Callable[[A], A]:  # pylint: disable=function-redefined
    ...  # pylint: disable=pointless-statement


    Returns the composed function.
    """

    def _(*args, **kw):
        ret = reduce(lambda acc, x: lambda f: f(acc(x)),
                     funcs[::-1],
                     lambda f: f(*args, **kw))
        return ret(lambda x: x)
    return _

compose2 = lambda f, g: compose(f, g)  # To force partial application

identity = compose()  # type: Callable
) -> Callable[[A], D]:
    ...  # pylint: disable=pointless-statement


@overload
def compose(
    op4: Callable[[D], E],  # pylint: disable=function-redefined
    op3: Callable[[C], D],
    op2: Callable[[B], C],
    op1: Callable[[A], B],
) -> Callable[[A], E]:
    ...  # pylint: disable=pointless-statement


@overload
def compose(
    op5: Callable[[E], F],  # pylint: disable=function-redefined
    op4: Callable[[D], E],
    op3: Callable[[C], D],
    op2: Callable[[B], C],
    op1: Callable[[A], B],
) -> Callable[[A], F]:
    ...  # pylint: disable=pointless-statement


@overload
def compose(
    op1: Callable[[A], B],  # pylint: disable=function-redefined,too-many-arguments
    op2: Callable[[B], C],
    op3: Callable[[C], D],
    op4: Callable[[D], E],
    op5: Callable[[E], F],
    op6: Callable[[F], G],
) -> Callable[[A], G]:
    ...  # pylint: disable=pointless-statement


def compose(*funcs: Callable) -> Callable:  # type: ignore
    """Compose multiple functions right to left.

    Composes zero or more functions into a functional composition. The
    functions are composed right to left. A composition of zero
    functions gives back the identity function.

    compose()(x) == x
    compose(f)(x) == f(x)
    compose(g, f)(x) == g(f(x))
    compose(h, g, f)(x) == h(g(f(x)))
    ...

    Returns the composed function.
    """

    def _compose(source: Any) -> Any:
        return reduce(lambda acc, f: f(acc), funcs[::-1], source)

    return _compose


fmap = lambda f, g: compose(f, g)  # To force partial application

identity = compose()  # type: Callable

<MSG> Moved compose to fn

<DFF> @@ -18,14 +18,14 @@ def compose(*funcs: "Tuple[Callable, ...]") -> Callable:
 
     Returns the composed function.
     """
-
-    def _(*args, **kw):
+    def _compose(*args, **kw):
+        """Reduce functions to a single function."""
         ret = reduce(lambda acc, x: lambda f: f(acc(x)),
                      funcs[::-1],
                      lambda f: f(*args, **kw))
         return ret(lambda x: x)
-    return _
+    return _compose
 
-compose2 = lambda f, g: compose(f, g)  # To force partial application
+fmap = lambda f, g: compose(f, g)  # To force partial application
 
 identity = compose()  # type: Callable

Moved compose to fn