标准 ML 求和函数

Standard ML sum function

我遇到了一个问题,系统要求我提供一个对给定变量 x 中的所有元素求和的函数。例如,sum([5,5,5]) 应该 return 15.

当我像这样测试单个整数的总和时,我的麻烦就来了:sum(5)

该函数应该能够在单个数字和数字列表之间返回和第四。我知道要做到这一点,我需要一个具有一些 Int of int | Null | ...

的数据类型

我的问题是如何使下面的代码适用于测试用例 sum(5);

fun sum(x) = if x = nil
             then 0
             else hd(x) + sum(tl(x))

val result = sum([5,5]);

我想我需要这样的东西:

else if (int? x) then x
else hd(x) + sum(tl(x))

但是当我对我的数据类型执行此操作时,我遇到了 int 与 int 列表的冲突。

快速回答您的问题:那是不可能的。正如您正确地说的那样,您需要一种数据类型,允许您保存单个整数或整数列表。您可以引入这样的类型:

datatype my_int = SingleInt of int | ManyInts of int list

fun sum (SingleInt i) = i
  | sum (ManyInts is) = foldl op+ 0 is

但这真的有点傻,因为如果你仔细想想,类型 int list 已经可以容纳单个整数或整数列表(甚至零整数,当涉及到总和时, 具有明确的含义)。因此,将您的功能扩展到处理列表之外是没有意义的。

而且无论您是否使用自定义类型,您都无法访问重载,因此在标准 ML 中无法编写 sum 5sum [5,5,5]。在其他函数式语言中,例如 Haskell,您可以使用 类.

类型实现这种重载

作为旁注,尝试使用模式匹配而不是 if-then-else。您的总和函数将是:

fun sum [] = 0
  | sum (x::xs) = x + sum xs

或者制作尾递归版本:

fun sum xs =
    let fun helper [] result = result
          | helper (x::xs) result = helper xs (x+result)
    in helper xs 0 end

或者简单地使用折叠:

val sum = foldl op+ 0