首页 文章

用于评估SML中的方程的Curried函数

提问于
浏览
-1

我需要解决的确切问题如下 .

基本上,我给出了一个实数的列表,代表系数 . 第一个元素是常数值,其后面的所有元素都是多项式方程的系数 . 因此,eval [1.0,5.0,3.0] 2.0将构建方程"1 + 5x + 3x^2"并将其评估为2.0,结果为23.0 . 该函数必须是"real list -> real -> real"类型 .

现在,我需要做的是使用curried函数在SML中实现eval,这样它就是一行,并且没有递归调用 . 我已经完成了递归的方式并且理解了这一点,但是我已经把烦恼缠绕在咖喱的方式上了 . 我们需要使用map,foldr和foldl等函数来完成此操作,以及匿名函数 . 我对此的想法是为了使函数获取列表并仅采用它的尾部(除了head元素,这是常量),并使用foldl进行评估 . 我遇到的问题是我已经走了(一个柜台),所以我可以正确使用他们的权力 .

任何帮助都将非常感激 .

1 回答

  • 0

    考虑到折叠函数,列表数据结构和尾递归是交织在一起的,如果您已经有一个尾递归解决方案,您可以轻松地使用基于折叠的解决方案 .

    可以使用实现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
    

    折叠器如何在这里工作?

    给出系数列表 [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调用匿名函数,并生成结果,该结果是评估的多项式的值 .

相关问题