Python中的monad错误 – 我做得对吗?
作者:互联网
问题:
>这是一个单子吗?
>这是否证明了对错误monad的合理理解?
>我错过了什么?
>我还能用这个代码做更多的flex monad吗?
>我对成功/失败与“返回”/“结果”/“提升”的关系感到困惑(我认为这些都是相同的概念).
>我们怎样才能使问题变得更加复杂,以至于monads帮助我们解决了我们的痛点? monads在这里提供帮助因为我们抽象了if结果!=没有管道,我想抽象出哪些其他类型的管道,monad(或’monad combinators’)如何帮助这种痛苦?
我有点不知所措.
# 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'")
解决方法:
这是一个单子吗?见monad laws:
All instances of the Monad class should obey:
- “Left identity”:
return a >>= f ≡ f a- “Right identity”:
m >>= return ≡ m- “Associativity”:
(m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
(返回表示成功,>> =表示绑定)
>左翼身份.在您的实现中,这可能是:
bind(success(x), balance_qualifies_for_loan) == balance_qualifies_for_loan(x)
其中x是某个值,f是monadic函数.
>正确的身份.同样,这可能是:
bind(m, success) == m
其中m是monadic值.
>相关性.这可能是:
bind(bind(m, userid_from_name), balance_from_userid)) ==
bind(m, lambda x: bind(userid_from_name(x), balance_from_userid))
所有这些都可以写成单元测试,以快速检查这些属性是否适用于许多输入值.
缺什么?
>每个monad需要不同的成功和绑定实现.将这些放入接口将允许您在所有实现的monad上编写通用代码.
>基于the Haskell approach,您可能想要实现一些通用的monad组合器,例如>>,sequence和mapM.这些使monad非常方便使用.
标签:python,monads 来源: https://codeday.me/bug/20190704/1376602.html