Repository: vickumar1981/pyeffects

Issue:
Add `on_success` callback to `Try` class
Add an `on_success` callback to the `Try` class, so that you can call a function w/o returning a value, when the `Try` succeeds.

Discussion:

Patch:
diff --git a/pyeffects/Try.py b/pyeffects/Try.py
index a7f108b..b0ab8d4 100644
--- a/pyeffects/Try.py
+++ b/pyeffects/Try.py
@@ -144,6 +144,37 @@ class Try(Monad[A]):
         """
         return not self.is_success()
 
+    def on_success(self, func: Callable[[A], None]) -> None:
+        """Calls a function on success.
+        
+        :rtype pyEffects.Try
+
+        Usage::
+
+          >>> from pyeffects.Try import *
+          >>> Try.of('abc').on_success(print)
+          abc
+        """
+
+        if self.is_success():
+            func(self.value)
+
+
+    def on_failure(self, func: Callable[[Exception], None]) -> None:
+        """Calls a function on failure.
+        
+        :rtype pyEffects.Try
+
+        Usage::
+
+          >>> from pyeffects.Try import *
+          >>> Failure(RuntimeError('Error!')).on_failure(print)
+          Error!
+        """
+
+        if self.is_failure():
+            func(self.error())
+
 
 class Failure(Try[A]):
     def __init__(self, value: Exception) -> None:
@@ -160,4 +191,4 @@ class Success(Try[A]):
         self.biased = True
 
     def __repr__(self) -> str:
-        return 'Success(' + str(self.value) + ')'
+        return 'Success(' + str(self.value) + ')'
\ No newline at end of file


Test patch:
diff --git a/tests/test_try.py b/tests/test_try.py
index d0d9b06..8e5fe32 100644
--- a/tests/test_try.py
+++ b/tests/test_try.py
@@ -68,6 +68,32 @@ class TestOption:
         result = Try.of(lambda: Success(random_int()).recovers(TypeError, random_int()))
         assert result.is_failure() and isinstance(result.error(), TypeError)
 
+    def test_try_on_success_done(self):
+        xs = [1, 2, 3]
+        Try.of(xs).on_success(lambda l: l.append(4))
+        assert xs == [1, 2, 3, 4]
+
+    def test_try_on_success_skipped(self):
+        def error():
+            raise RuntimeError()
+
+        xs = [1, 2, 3]
+        Try.of(error).on_success(lambda _: xs.append(4))
+        assert xs == [1, 2, 3]
+    
+    def test_try_on_failure_done(self):
+        def error():
+            raise RuntimeError('Error!')
+
+        errors = []
+        Try.of(error).on_failure(lambda e: errors.append(str(e)))
+        assert errors == ['Error!']
+
+    def test_try_on_failure_skipped(self):
+        errors = []
+        Try.of([1, 2, 3]).on_failure(lambda e: errors.append[str(e)])
+        assert not errors
+
     def test_try_repr(self):
         assert str(Success(random_int())).startswith("Success")
         assert str(Failure(random_int())).startswith("Failure")