Skip to content

Instantly share code, notes, and snippets.

@yxy
Last active September 16, 2021 17:03
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save yxy/77bb0947909ba35c535d21e83a074ab9 to your computer and use it in GitHub Desktop.
Save yxy/77bb0947909ba35c535d21e83a074ab9 to your computer and use it in GitHub Desktop.
Railway Oriented Programming in python. inspired by https://fsharpforfunandprofit.com/rop/
class Success(object):
def __init__(self, value):
self.value = value
class Error(object):
def __init__(self, value):
self.value = value
class wrapper(object):
def __init__(self, result):
self.result = result
def success(self, func):
if isinstance(self.result, Success):
func(self.result.value)
return self
def fail(self, func):
if isinstance(self.result, Error):
func(self.result.value)
return self
def compose(*func):
def f(x):
r = Success(x)
for f in func:
if isinstance(r, Error): break
r = f(r.value)
return wrapper(r)
return f
def validate(data):
if data.get('f', None):
return Success(data)
return Error({'error': 'field f required'})
def create_user(data):
print('create user named ' + data['f'])
return Success(data)
def send_email(data):
try:
raise IOError("failed to send error")
except IOError as e:
return Error(e)
req = {'f': '1'}
f = compose(validate, create_user, send_email)
def success(r):
print("Success, ", r)
def fail(r):
print("Failed: ", r)
f(req).success(success).fail(fail)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment