【问题标题】:Standard ML sum function标准 ML sum 函数
【发布时间】:2016-01-19 18:08:53
【问题描述】:

我有一个问题,我被要求提供一个函数,该函数将给定变量x 中的所有元素相加。例如,sum([5,5,5]) 应该返回 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 列表的冲突。

【问题讨论】:

  • 使用您建议的数据类型,测试用例将类似于sum (Int 5)sum Null,而不是sum [5,5,5]。请详细说明该功能应该做什么。
  • 嗯,这里的目标是将 LISP 函数转换为 ML。 lisp 函数不仅适用于列表,还适用于由 (is number?) 检查的单个原子数值。显然,在这里引用另一个响应,这在标准 ML 中是不可能的。引用单个 int 和列表。 sum([5,5,5]) 已经按原样工作了。需要 sum(5) 来返回 5 是我的问题。

标签: function types sml ml


【解决方案1】:

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

datatype my_int = SingleInt of int | ManyInts of int list

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

但这确实有点傻,因为如果你仔细想想,int list 类型已经可以保存一个整数或一个整数列表(甚至是零整数,当涉及到 sum 时,它有一个很好的-定义的含义)。因此,将您的功能扩展到处理列表之外是没有意义的。

无论您是否使用自定义类型,您都无法访问重载,因此在标准 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

【讨论】:

  • 谢谢,你说得对,只是我尝试转换的代码以这种方式为 LISP 工作似乎是多余的,有人告诉我应该很容易地将其转换为 ML。好像不是这样的。
  • 大多数 Lisps 不是强类型的,因此它们允许函数/宏接受各种输入(甚至是可变数量的参数),而 ML 的类型系统更受限制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
  • 1970-01-01
  • 2018-08-23
相关资源
最近更新 更多