简体   繁体   English

从命令式编程转换为函数式编程[Python到标准ML]

[英]Conversion from imperative to functional programming [Python to Standard ML]

I have a function specification that states it that should evaluate a polynomial function of one variable. 我有一个函数规范,声明它应该评估一个变量的多项式函数。 The coefficient of the function is given as a list. 函数系数以列表形式给出。 It also accepts the value of the variable as a real. 它还接受变量的值作为实数。

For example: eval(2, [4, 3, 2, 1]) = 26 (1*x^3 + 2*x^2 + 3*x^1 + 4*x^0, where x = 2) 例如:eval(2,[4,3,2,1])= 26(1 * x ^ 3 + 2 * x ^ 2 + 3 * x ^ 1 + 4 * x ^ 0,其中x = 2)

Here's the function in python, but I'm not sure how to convert it to SML. 这是python中的函数,但我不确定如何将其转换为SML。 I'm having trouble finding a way to pass it the iteration value without changing the parameters of the function. 我无法找到一种方法来传递迭代值,而无需更改函数的参数。 It needs to remain a real * real list -> real function. 它需要保持真正的真实列表 - >真正的功能。

def eval(r, L):
    sum = 0
    for i in range(0, len(L)):
        sum = sum + L[i] * (r ** i)
    return sum

The usual way to express sums in functional languages is a fold. 在函数式语言中表达总和的通常方法是折叠。 You can get rid of the need for an index (and a function to raise an int to the power of another int) by multiplying the sum with r in each iteration: 你可以通过在每次迭代中将sum乘以r来摆脱索引(以及将int提升到另一个int的幂的函数)的需要:

fun eval radix lst = let
  fun f (element, sum) = sum * radix + element
in
  foldr f 0 lst
end

Now the function can be used like this: 现在这个函数可以像这样使用:

- eval 10 [1,2,3];
val it = 321 : int

You can use explicit recursion to walk through the list of coefficients, exponentiate the radix, and sum up the total. 您可以使用显式递归来遍历系数列表,对基数取幂,并总计总和。

fun eval r =
    let fun step (power, sum) (coeff :: rest) =
                step (power * r, sum + coeff * power) rest
          | step (_, sum) nil = sum
    in step (1, 0)
    end

Structurally, this is exactly like a fold, and it becomes clearer if we replace it with one. 在结构上,这就像折叠一样,如果我们用一个替换它就会变得更清晰。

fun eval r lst =
    let fun step (coeff, (power, sum)) = (power * r, sum + coeff * power)
        val (_, sum) = foldl step (1, 0) lst
    in sum
    end

You can reverse the order of operations to use Horner's scheme, as mentioned in KennyTM's comment: that would result in sepp2k's answer, which requires half as many multiplications, but uses more stack space. 你可以颠倒操作的顺序来使用Horner的方案,正如KennyTM的评论中提到的那样:这将导致sepp2k的答案,这需要一半的乘法,但使用更多的堆栈空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM