<NME> reader.py
<BEF> from functools import partial

from typing import Callable, Any, TypeVar, Generic

from .typing import Functor
from .typing import Monad
from .typing import Applicative

TEnv = TypeVar("TEnv")
TSource = TypeVar("TSource")
TResult = TypeVar("TResult")


class Reader(Generic[TEnv, TSource]):
    """The Reader monad.

    The Reader monad pass the state you want to share between functions.
    Functions may read that state, but can't change it. The reader monad
    lets us access shared immutable state within a monadic context.

    The Reader is just a fancy name for a wrapped function, so this
    monad could also be called the Function monad, or perhaps the
    Callable monad. Reader is all about composing wrapped functions.
    """

    def __init__(self, fn: Callable[[TEnv], TSource]) -> None:
        """Initialize a new reader."""

        self.fn = fn

    @classmethod
    def unit(cls, value: TSource) -> "Reader[TEnv, TSource]":
        r"""The return function creates a Reader that ignores the
        environment and produces the given value.

        return a = Reader $ \_ -> a
        """
        return cls(lambda _: value)

    def map(self, fn: Callable[[TSource], TResult]) -> "Reader[TEnv, TResult]":
        r"""Map a function over the Reader.

        Haskell:
        fmap f m = Reader $ \r -> f (runReader m r).
        fmap f g = (\x -> f (g x))
        """

        def _compose(x: Any) -> Any:
            return fn(self.run(x))

        return Reader(_compose)

    def bind(self, fn: "Callable[[TSource], Reader[TEnv, TResult]]") -> "Reader[TEnv, TResult]":
        r"""Bind a monadic function to the Reader.

        Haskell:
        Reader: m >>= k  = Reader $ \r -> runReader (k (runReader m r)) r
        Function: h >>= f = \w -> f (h w) w
        """
        return Reader(lambda x: fn(self.run(x)).run(x))

    @classmethod
    def pure(cls, fn: Callable[[TSource], TResult]) -> "Reader[TEnv, Callable[[TSource], TResult]]":
        return Reader.unit(fn)

    def apply(
        self: "Reader[TEnv, Callable[[TSource], TResult]]", something: "Reader[TEnv, TSource]"
    ) -> "Reader[TEnv, TResult]":
        r"""(<*>) :: f (a -> b) -> f a -> f b.

        Haskell: f <*> g = \x -> f x (g x)

        Apply (<*>) is a beefed up map. It takes a Reader that
        one (composes the two functions).
        """

        g = something.run()

        def _compose(x):
            f = self(x)
            try:
                ret = f(g(x))
            except TypeError:
                ret = partial(f, g(x))
            return ret

        return Reader(_compose)
                return partial(fn, value)

        return Reader(comp)

    def run(self, env: TEnv) -> TSource:
        """Run reader in given environment.

        Haskell: runReader :: Reader r a -> r -> a

        Applies given environment on wrapped function.
        """
        return self.fn(env)

    def __call__(self, env: TEnv) -> TSource:
        """Call the wrapped function."""

        return self.run(env)

    def __str__(self) -> str:
        return "Reader(%s)" % repr(self.fn)
        return equal

    def __str__(self) -> str:
        return "Reader(%s)" % self.fn()

    def __repr__(self) -> str:
        return str(self)

# Our version of underscore
_ = Reader


class MonadReader(Reader):

    """

    @classmethod
    def ask(cls) -> Reader[TEnv, TEnv]:
        r"""Reader $ \x -> x

        Provides a way to easily access the environment.
        ask lets us read the environment and then play with it
        """
        return Reader(lambda x: x)

    @classmethod
    def asks(cls, fn: Callable[[TEnv], TSource]) -> Reader[TEnv, TSource]:
        return cls(lambda x: x)

    @classmethod
    def asks(cls, func: Callable) -> Reader:
        """
        Given a function it returns a Reader which evaluates that
        function and returns the result.
            return $ f e

        asks sel = ask >>= return . sel
        """


        asks sel = ask >>= return . sel
        """
        return cls.ask().bind(Reader(lambda e: cls.unit(func(e))))

    def local(self, func) -> Reader:
        r"""local transforms the environment a Reader sees.

        local f c = Reader $ \e -> runReader c (f e)
        """
        return Reader(lambda e: self.run(func(e)))
assert isinstance(Reader, Applicative)
assert isinstance(Reader, Monad)

<MSG> func to fn

<DFF> @@ -74,14 +74,12 @@ class Reader(Monad, Applicative, Functor):
         one (composes the two functions).
         """
 
-        g = something.run()
-
         def _compose(x):
             f = self(x)
             try:
-                ret = f(g(x))
+                ret = f(something(x))
             except TypeError:
-                ret = partial(f, g(x))
+                ret = partial(f, something(x))
             return ret
 
         return Reader(_compose)
@@ -108,14 +106,11 @@ class Reader(Monad, Applicative, Functor):
         return equal
 
     def __str__(self) -> str:
-        return "Reader(%s)" % self.fn()
+        return "Reader(%s)" % repr(self.fn)
 
     def __repr__(self) -> str:
         return str(self)
 
-# Our version of underscore
-_ = Reader
-
 
 class MonadReader(Reader):
 
@@ -135,7 +130,7 @@ class MonadReader(Reader):
         return cls(lambda x: x)
 
     @classmethod
-    def asks(cls, func: Callable) -> Reader:
+    def asks(cls, fn: Callable) -> Reader:
         """
         Given a function it returns a Reader which evaluates that
         function and returns the result.
@@ -147,11 +142,11 @@ class MonadReader(Reader):
 
         asks sel = ask >>= return . sel
         """
-        return cls.ask().bind(Reader(lambda e: cls.unit(func(e))))
+        return cls.ask().bind(Reader(lambda x: cls.unit(fn(x))))
 
-    def local(self, func) -> Reader:
+    def local(self, fn) -> Reader:
         r"""local transforms the environment a Reader sees.
 
         local f c = Reader $ \e -> runReader c (f e)
         """
-        return Reader(lambda e: self.run(func(e)))
+        return Reader(lambda x: self(fn(x)))

func to fn