diff --git a/pyresult/__init__.py b/pyresult/__init__.py index 41382c4..8e53c37 100644 --- a/pyresult/__init__.py +++ b/pyresult/__init__.py @@ -16,6 +16,7 @@ and_then, and_else, resolve, + do, ) __author__ = """Jindrich Kralevic Smitka""" diff --git a/pyresult/operators.py b/pyresult/operators.py index b109910..3928cd6 100644 --- a/pyresult/operators.py +++ b/pyresult/operators.py @@ -60,15 +60,15 @@ def fold(res): fold: (List Result a x) -> Result (List a) (List x) ''' len_res = len(res) - val = [None]*len_res - err = [None]*len_res + val = [None] * len_res + err = [None] * len_res - for i, e in enumerate(res): - e = result(e) - if is_ok(e): - val[i] = e.value + for i, item in enumerate(res): + result_item = result(item) + if is_ok(result_item): + val[i] = result_item.value else: - err[i] = e.value + err[i] = result_item.value if None in val: return error(err) @@ -83,3 +83,15 @@ def resolve(res): ''' res = result(res) return res if is_error(res) else result(res.value) + + +def do(func, res): # pylint: disable=invalid-name + '''Run `func` when result `res` is ok + and then return `res` if function return ok result, + otherwise return its error result. + + do: (val -> Result x e) -> Result val e -> Result val e + ''' + res = result(res) + + return and_then(lambda _: res, func(res.value)) if is_ok(res) else res diff --git a/tests/test_operators.py b/tests/test_operators.py index 40e81ea..9797a16 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -9,7 +9,8 @@ and_then, and_else, fold, - resolve + resolve, + do ) @@ -113,3 +114,21 @@ def test_resolve_isnt_ok(): val = (OK, (OK, 'val')) assert resolve(val) == (OK, 'val') + + +def test_do_return_original_error(): + err = error('ERROR') + + assert do(ok, err) == err + + +def test_do_return_original_result(): + result = ok('FOO BAR') + + assert do(lambda _: ok('BAZ FOO'), result) == result + + +def test_do_return_error_from_function(): + err = error('BAZ FOO') + + assert do(lambda _: err, ok('FOO BAR')) == err