我正在尝试在 python 中实现 Maybe monad。 然而,我还想要某种链接能力。
所以我有一个类:
class Maybe:
def __init__(self, val):
self.val = val
def do(self, func): # Bind function
if self.val is None:
return None
else:
return func(self.val)
我有两个功能:
def double(number):
try:
result = number * 2
return Maybe(result)
except:
return Maybe(None)
def square(number):
try:
result = number * number
return Maybe(result)
except:
return Maybe(None)
我是这样使用的:
result = Maybe(5).do(double).do(square)
print(result.val)
我正在寻找一种方法来链接多个函数,每个函数执行特定任务。每个函数都将前一个函数的输出作为输入。如果链中的任何函数抛出异常,则链应该中断。
这是对 Maybe monad 建模的正确方法吗?
这也是处理异常的正确方法吗?
这可以改进吗?
非常感谢。
最佳答案
这样做的缺点是它有意抑制错误,这在 Python 中通常被认为是一个坏主意。
但是,您可以捕获并存储在您的 Maybe
实例中发生的任何错误,并将它们报告回来。
例如:
class Maybe(object):
def __init__(self, val, error=None):
self.val = val
self.error = error
def __repr__(self):
if self.val is not None:
return repr(self.val)
else:
return repr(self.error)
def do(self, func):
if self.val is None:
return self
try:
return Maybe(func(self.val))
except Exception as e:
return Maybe(None, e)
def squared(x):
return x * x
def addone(x):
return x + 1
result1 = Maybe(5).do(squared).do(addone)
result2 = Maybe('a').do(squared).do(addone)
print result1
print result2
这会产生:
26
TypeError("can't multiply sequence by non-int of type 'str'",)
这类似于 DanD 的回答,但具有存储发生的错误而不是完全抑制错误的优点。
无论您如何剖析它,这个习语都会让人觉得有些“非 Python 风格”,但这是一种稍微更稳健的处理方式。
关于python - 也许 Python 中的 monad 带有方法链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28607666/