4
- 这是一个monad吗?
- 这是否证明了错误monad的合理理解?
- 我错过了什么?
- 我还可以用这个代码来做更多的单子吗?
- 我对成功/失败与“返回”/“结果”/“提升”的关系感到困惑(我认为这些都是相同的概念)。
- 我们如何才能使问题更加复杂,让monad帮助我们解决我们的痛点? monads在这里帮助我们,因为我们抽象出了管道,我想抽象什么其他类型的管道,以及单子(或单子组合器)如何帮助这种痛苦?
我有点不知所措。
# helpers for returning error codes
def success(x): return (True, x)
def fail(x): return (False, x)
# bind knows how to unwrap the return value and pass it to
# the next function
def bind(mv, mf):
succeeded = mv[0]
value = mv[1]
if (succeeded): return mf(value)
else: return mv
def lift(val): return success(val)
def userid_from_name(person_name):
if person_name == "Irek": return success(1)
elif person_name == "John": return success(2)
elif person_name == "Alex": return success(3)
elif person_name == "Nick": return success(1)
else: return fail("No account associated with name '%s'" % person_name)
def balance_from_userid(userid):
if userid == 1: return success(1000000)
elif userid == 2: return success(75000)
else: return fail("No balance associated with account #%s" % userid)
def balance_qualifies_for_loan(balance):
if balance > 200000: return success(balance)
else: return fail("Insufficient funds for loan, current balance is %s" % balance)
def name_qualifies_for_loan(person_name):
"note pattern of lift-bind-bind-bind, we can abstract further with macros"
mName = lift(person_name)
mUserid = bind(mName, userid_from_name)
mBalance = bind(mUserid, balance_from_userid)
mLoan = bind(mBalance, balance_qualifies_for_loan)
return mLoan
for person_name in ["Irek", "John", "Alex", "Nick", "Fake"]:
qualified = name_qualifies_for_loan(person_name)
print "%s: %s" % (person_name, qualified)
输出:
Irek: (True, 1000000)
John: (False, 'Insufficient funds for loan, current balance is 75000')
Alex: (False, 'No balance associated with account #3')
Nick: (True, 1000000)
Fake: (False, "No account associated with name 'Fake'")
非常好的问题。我认为代码是好的,因为它是,但它可以通过重载''>>操作和使用lambda表达式来五香了很多。一个完全不同的方法是从[这里]所述一个(http://www.valuedlessons.com/2008/01/monads-in-python-with-nice-syntax.html),那个人使用的装饰和'yield'到让这个几乎看起来是正确的:) – 2012-04-04 02:02:01
我稍微调整了代码,使其更具可读性。希望你不介意(如果你这样做,请将它回滚:) – 2012-04-04 02:07:42