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

发布于 2024-08-22 16:32:21 字数 370 浏览 5 评论 0原文

我有一个函数规范,指出它应该评估一个变量的多项式函数。函数的系数以列表形式给出。它还接受变量的实数值。

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

这是python 中的函数,但我不知道如何将其转换为 SML。我无法找到一种在不更改函数参数的情况下向其传递迭代值的方法。它需要保持一个真实的*真实的列表->实函数。

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

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)

Here's the function in python, but I'm not sure how to convert it to 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凹づ凸ル 2024-08-29 16:32:21

在函数语言中表达和的常用方法是折叠。您可以通过在每次迭代中将总和与 r 相乘来消除对索引(以及将一个 int 提升为另一个 int 次幂的函数)的需要:

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

现在可以像这样使用该函数:

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

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:

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
爱给你人给你 2024-08-29 16:32:21

您可以使用显式递归来遍历系数列表、对基数求幂并对总数求和。

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

从结构上来说,这和折叠一模一样,如果我们把它换成折叠就更清楚了。

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

您可以反转操作顺序以使用 Horner 的方案,如 KennyTM 的评论中所述:这将导致 sepp2k 的答案,它需要一半的乘法,但使用更多的堆栈空间。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文