【发布时间】:2011-05-29 14:12:47
【问题描述】:
考虑以下命令式代码,它在 3 位数字的乘积中找到最大的回文(是的,这是“[18 世纪杰出数学家] 项目”网站的第一个任务):
curmax = 0
for i in range(999,100):
for j in range(999,100):
if ((i*j) < curmax): break
if (pal(i*j)):
curmax = i*j
break
print curmax
当我目前正在学习 Haskell 时,我的问题是,你如何翻译这个(以及基本上任何包含比简单迭代更复杂的东西的命令式构造,例如中断、继续、临时变量以及所有这些)到 Haskell?
我的版本是
maxpal i curmax
| i < 100 = curmax
| otherwise = maxpal (i-1) (innerloop 999)
where
innerloop j
| (j < 100) || (p < curmax) = curmax
| pal p = p
| otherwise = innerloop (j-1)
where p = i*j
main = print $ maxpal 999 0
但这看起来我们仍然处于势在必行的丑陋之城。
那么你有什么建议,FP风格的处理这种情况的方法是什么?
【问题讨论】:
-
好吧,如果您尝试将命令式控制流转换为 Haskell,那么您将进入命令式丑陋小镇,几乎按照定义。
-
这才是真正的问题:不是如何盲目地将命令式代码转换为 Haskell 语法,而是在函数式编程中使用什么方法来优雅地处理复杂的流程。
-
这可能有点格格不入,但我通常不会从命令式转换为函数式,而是返回规范(规范通常不关心控制流)并从那里开始工作。当您确实有复杂的控制流时,延续传递风格 (CPS) 和惰性求值(可以将生产与中间值的消费分开)是抽象复杂性的两种有价值的技术。
标签: haskell functional-programming imperative-programming