Skip to content

Instantly share code, notes, and snippets.

@ahammel
Last active August 29, 2015 14:01
Show Gist options
  • Select an option

  • Save ahammel/ef978511dad42479fd31 to your computer and use it in GitHub Desktop.

Select an option

Save ahammel/ef978511dad42479fd31 to your computer and use it in GitHub Desktop.
class Nothing(object):
"""Represents a failed computation.
"""
class TryChain(object):
"""Apply a series of functions to a value, keeping only the first one that
fails to throw a user-specified exception.
"""
def __init__(self, exception):
self._exception = exception
self.error = Nothing
self.value = Nothing
def bind(self, function):
"""If the value of the chain is Nothing, call the (nullary) function
and apply it to the value.
If the function call raises an exception, store the value of that
exception in error property.
"""
if self.value is Nothing:
try:
self.value = function()
except self._exception as error:
self.error = error
c = TryChain(ZeroDivisionError)
try:
c.bind(lambda : int("frob"))
except ValueError as e:
print(e) # => invalid literal for int() with base 10: 'frob'
if c.value is Nothing:
print("Nothing")
c.bind(lambda : 1 / 0)
c.bind(lambda : 4 / 2)
c.bind(lambda : 5 / 3)
print(c.value) # => 2
print(c.error) # => division by zero
@ethanfurman
Copy link

The print() in the try/exect doesn't do anything as .bind() doesn't reraise the exception (no ValueError is raised).

@ahammel
Copy link
Author

ahammel commented May 22, 2014

Ah, right you are. Had it the wrong way around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment