Adjust signatures of Reader instances

This commit is contained in:
Correl Roush 2019-01-08 13:48:13 -05:00 committed by Correl Roush
parent 116c3cc1ac
commit a45af9b5b0
2 changed files with 24 additions and 3 deletions

View file

@ -1,5 +1,6 @@
from __future__ import annotations
from functools import reduce, update_wrapper
import inspect
from typing import Any, Callable, Generic, Iterable, List, TypeVar
from .monad import Monad
@ -20,8 +21,22 @@ class Reader(Monad[T], Generic[Env, T]):
@classmethod
def pure(cls, value: T) -> Reader[Env, T]:
f: F = lambda x: value
return cls(f)
class constant:
def __call__(self, _: Env) -> T:
return value
# Update the signature's return annotation to reflect the
# concrete type of the wrapped value.
__signature__ = inspect.Signature(
[
inspect.Parameter(
"_", inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=Any
)
],
return_annotation=type(value),
)
return cls(constant())
def map(self, function: Callable[[T], S]) -> Reader[Env, S]:
f: Callable[[Env], S] = lambda x: function(self.function(x))
@ -51,7 +66,8 @@ class Reader(Monad[T], Generic[Env, T]):
def __repr__(self): # pragma: no cover
module = self.function.__module__
name = self.function.__name__
return f"<Reader {module}.{name}>"
signature = inspect.signature(self)
return f"<Reader {module}.{name}{signature}>"
__mul__ = __rmul__ = map
__rshift__ = bind

View file

@ -1,3 +1,4 @@
import inspect
import pytest # type: ignore
from typing import Any, Callable, List, TypeVar
@ -86,3 +87,7 @@ def test_monad_associativity() -> None:
return Reader.pure(n + 5)
assert m.bind(f).bind(g)(0) == m.bind(lambda x: f(x).bind(g))(0)
def test_pure_annotation_includes_concrete_type() -> None:
assert int == inspect.signature(Reader.pure(5)).return_annotation