我需要解决的确切问题如下。
基本上,我得到一个实数的列表,代表系数。第一个元素是常数值,其后面的所有元素都是多项式方程的系数。因此, eval [1.0,5.0,3.0] 2.0将构建方程" 1 + 5x + 3x ^ 2"并将其评估为2.0,结果为23.0。该函数需要是"真实列表 - >类型。真实的 - >真实"
现在,我需要做的是使用curried函数在SML中实现 eval ,这样它就是一行,并且没有递归调用。我已经完成了递归的方式并理解了这一点,但是我已经把烦恼缠绕在咖喱的方式上了。我们需要使用 map , foldr 和 foldl 等函数来完成此操作,以及匿名函数。我对此的想法是为了使函数获取列表并仅取其尾部(除了head元素,这是常量),并使用 foldl 进行评估。我遇到的问题是我不确定这是否可行,或者如何通过跟踪我已经离开的列表(计数器)的距离来实现这一点,以便我可以正确使用他们的权力。
非常感谢任何帮助。
答案 0 :(得分:0)
考虑到 fold 函数,列表数据结构和尾递归交织在一起,您可以轻松地使用基于折叠的方式解决方案,如果你已经有一个尾递归解决方案。
使用实现 horners方法的递归函数可以解决评估多项式的问题:
fun eval [] _ = 0.0
| eval (y :: ys) x = y + x*(eval ys x)
该函数可以很容易地转换为尾递归函数,之后应该出现使用 foldr 的解决方案:
fun eval ys x = foldr (fn (y,a) => y + x*a) 0.0 ys
那么 foldr 如何在这里工作?
给出一个系数列表[y0,y1,y2,y3]
,它代表以下多项式f(x)=y0+y1*x+y2*x^2+y3*x^3
。
foldr 会将匿名函数fn (y,a) => y + x*a
应用于
系列列表一步一步。它从右到右处理列表
剩下。它将第一个参数 y 作为其中的系数
遵循顺序(第一个y3,然后是y2,然后是y1,最后是y0)。
第二个
参数 a 确实包含评估的临时结果。参数 a 通常称为累加器。第一
它是用0.0
初始化的。在下一步,累加器保持值y3*x
。然后累加器保持值
y2*x+y3*x^2
。之后它保持y1*x+y2*x^2+y3*x^3
的值。最后,使用系数y0调用匿名函数,它产生结果,即得到的多项式的值。