Skip to content

Instantly share code, notes, and snippets.

@hachibeeDI
Created May 14, 2014 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hachibeeDI/532820a6d84bc5eb0d2d to your computer and use it in GitHub Desktop.
Save hachibeeDI/532820a6d84bc5eb0d2d to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
from __future__ import (print_function, division, absolute_import, unicode_literals, )
class Monad(object):
def __init__(self, v):
self.value = v
def __repr__(self):
return '{0}: < {1} >'.format(self.__class__.__name__, unicode(self.value))
def bind(self, a_to_m_b):
raise NotImplementedError
def map(self, a_b):
raise NotImplementedError
def __rshift__(self, a_to_m_b):
''' >> '''
return self.bind(a_to_m_b)
class Either(Monad):
@classmethod
def right(cls, var=None):
return Right(var)
@classmethod
def left(cls, var=None):
return Left(var)
def __nonzero__(self):
return self.is_right()
def is_left(self):
return self.__class__.__name__ == 'Left'
def is_right(self):
return self.__class__.__name__ == 'Right'
def match(self, right, left):
mytype = self.__class__.__name__
if mytype == 'Right':
return right(self.value)
elif mytype == 'Left':
return left(self.value)
else:
assert False, 'Unexpected value'
class Left(Either):
def bind(self, a_to_m_b):
return self
def map(self, a_b):
return self
def __eq__(self, other):
return isinstance(other, Left)
class Right(Either):
def bind(self, a_to_m_b):
return a_to_m_b(self.value)
def map(self, a_b):
return self
def __eq__(self, other):
if not isinstance(other, Right):
return False
return self.value == other.value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment