【发布时间】:2022-01-05 21:00:39
【问题描述】:
我有这个函数返回错误的结果
def calc(a): return lambda op: {
'+': lambda b: calc(a+b),
'-': lambda b: calc(a-b),
'*': lambda b: calc(a*b),
'/': lambda b: calc(a/b),
'=': a}[op]
calc(1)('+')(2)('*')(10)('=') # 30 -> should be 21
有谁知道如何保持函数式风格并遵循正确的数学顺序?
【问题讨论】:
-
如果你正在寻找柯里化,Haskell 基本上是围绕这个概念构建的,而 Python 则完全没有。您可能可以自己实现它,但它不值得痛苦,IMO
-
add(1, mul(2, 10))。不要试图在你的表达式中镜像中缀符号。 (add和mul是在operator模块中预定义的,以及其他运算符的函数。) -
Python 不是函数式语言。您可以使用
lambda函数和map和reduce编写一些功能性代码,但仅此而已。如果您想要一种纯函数式的方法,那么您正在寻找 Haskell。我认为还有其他纯函数式语言,但 Python 不是其中之一。同样,您可以在 Python 中模拟函数式样式,但这就像用叉子吃汤一样 - 不是非常有效或富有成效。 -
@KellyBundy,我不确定柯里化是否与运算符优先级有很大关系。 AFAIK,运算符优先级是在解析期间完成的,但currying是在运行时完成的。如果您以正确的顺序调用柯里化函数,您将获得正确的运算符优先级。
-
因为
a也可以是一个子表达式,你可以简单地写成calc(1)('+')(calc(2)('*')(10)('='))('=')。否则,您需要为每个运算符分配优先级并累积传递给calc的所有运算符(在评估之前),以按优先级确定的顺序排列它们。此外,您还必须将括号作为复合运算符引入。对于一个有趣的项目来说,这可能是太多工作了..
标签: python functional-programming