Created
November 20, 2019 21:19
-
-
Save kalebo/65642ac3d9326a6916bb1be7334cc353 to your computer and use it in GitHub Desktop.
Result monad for Python
This file contains hidden or 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
class Result(metaclass=ABCMeta): # abstract base class | |
'''A result monad whose interface is patterned after that of Rust's std::Result<T, E> ''' | |
def is_ok(self) -> bool: return NotImplemented | |
def unwrap_or_else(self, func): return NotImplemented | |
def unwrap_or(self, val): return NotImplemented | |
def then(self, f): return NotImplemented # techincally this breaks the monad rules because f might be a functor (A->Result(B)) or it could be just a function (A->B) | |
class Error(Result): | |
def __init__(self, err): | |
self._err = err | |
def __repr__(self): | |
return f"Error: {self._err}" | |
def is_ok(self): | |
return False | |
def unwrap_or_else(self, f): | |
return f(self._err) | |
def unwrap_or(self, v): | |
return v | |
def then(self, _): | |
return Error(self._err) | |
class Ok(Result): | |
def __init__(self, val): | |
self._val = val | |
def __repr__(self): | |
return f"Ok: {self._val}" | |
def is_ok(self): | |
return True | |
def unwrap_or_else(self, _): | |
return self._val | |
def unwrap_or(self, _): | |
return self._val | |
def then(self, f): | |
return f(self._val) | |
def wrap_in_result(f): | |
if inspect.iscoroutinefunction(f): # this idea for handling async functions came from https://github.com/dry-python/returns | |
async def decorator(*args, **kwargs): | |
try: | |
return Ok(await f(*args, **kwargs)) | |
except Exception as e: | |
return Error(e) | |
else: | |
def decorator(*args, **kwargs): | |
try: | |
return Ok(f(*args, **kwargs)) | |
except Exception as e: | |
return Error(e) | |
return decorator |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment