Created
August 31, 2020 11:20
-
-
Save sobolevn/a860b7e00e58298b1fcdfbb21ae4f7a2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Any, TypeVar, Callable, Generic, Optional, TYPE_CHECKING | |
from returns.functions import compose | |
if not TYPE_CHECKING: | |
reveal_type = print | |
T = TypeVar('T') | |
N = TypeVar('N') | |
class Maybe(Generic[T]): | |
_inner_value: Optional[T] | |
@classmethod | |
def from_value(cls, inner_value: Optional[T]) -> 'Maybe[T]': | |
if inner_value is None: | |
return Nothing | |
return _Some(inner_value) # type: ignore | |
def map(self, function: Callable[[T], N]) -> 'Maybe[N]': | |
... | |
def opt(self, function: Callable[[T], Optional[N]]) -> 'Maybe[N]': | |
... | |
def __str__(self) -> str: | |
return '{0}: {1}'.format(self.__class__.__name__, self._inner_value) | |
def __eq__(self, other) -> bool: | |
return type(self) == type(other) and self._inner_value == other._inner_value | |
class _Some(Maybe[Optional[T]]): | |
def __init__(self, inner_value: Optional[T]) -> None: | |
self._inner_value = inner_value | |
def map(self, function): | |
return _Some(function(self._inner_value)) | |
def opt(self, function): | |
return Maybe.from_value(function(self._inner_value)) | |
class _Nothing(Maybe[None]): | |
def __init__(self, inner_value: None) -> None: | |
... | |
def map(self, function): | |
return self | |
def opt(self, function): | |
return self | |
def Some(inner_value: T) -> Maybe[T]: | |
assert inner_value is not None | |
return _Some(inner_value) # type: ignore | |
Nothing: Maybe[Any] = _Nothing(None) | |
# testing | |
def f(arg: int) -> Optional[int]: | |
if arg == 0: | |
return None | |
return arg | |
def g(arg: Optional[int]) -> str: | |
return str(arg) | |
reveal_type(Maybe.from_value(1).map(f)) | |
reveal_type(Maybe.from_value(1).opt(f)) | |
# laws: | |
fg = compose(f, g) | |
reveal_type(Maybe.from_value(0).map(f).map(g)) | |
reveal_type(Maybe.from_value(0).map(fg)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment