Skip to content

Instantly share code, notes, and snippets.

@sobolevn
Created August 31, 2020 11:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sobolevn/a860b7e00e58298b1fcdfbb21ae4f7a2 to your computer and use it in GitHub Desktop.
Save sobolevn/a860b7e00e58298b1fcdfbb21ae4f7a2 to your computer and use it in GitHub Desktop.
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