5

定义一个函数,该函数计算给定整数列表中所有整数的总和。没有“if-then-else”或任何辅助功能。

我是函数式编程的新手,并且在使用 SML 的正确语法方面遇到了麻烦。为了解决这个问题,我尝试使用模式匹配创建一个函数,该函数只添加列表的前两个元素。完成这项工作后,我将使用递归来添加其余元素。不过,我什至无法编译这个简单的函数。

fun listAdd [_,[]] = 0
|   listAnd [[],_] = 0
|   listAnd [[x::xs],[y::ys]] = x + y;
4

3 回答 3

3
fun listAdd [] = 0
  | listAdd ([]::L) = listAdd L
  | listAdd ((x::xs)::L) = x + listAdd (xs::L)

应该做你想做的事情。

此外,您的函数的部分问题似乎是您在不同的子句中为函数赋予了不同的名称(listAdd 和 listAnd)。

于 2013-09-13T19:04:38.193 回答
1

为了简单起见,我想说你可能想要这个:

fun listAdd : (int * int) list -> int list

现在,我将其简单地定义为 unzip 函数的抽象:

fun listAdd ls :
    case ls of 
        [] => 0
      | (x,y) :: ls' => (x + y) + (listAdd ls')

我认为拿两个单独的清单是没有意义的。只需获取一个包含整数乘积的列表。如果你必须构建它,你可以调用 zip 函数:

fun zip xs ys :
    case xs, ys of
        [], [] => []
      | xs, _ => []
      | _, ys => []
      | x::xs', y::ys' => (x,y) :: (zip xs' ys')

一般来说,如果你真的想要,你可以编写一个更抽象的通用类型函数:

fun absProdList : ((`a * `b) -> `c) -> (`a * `b) list -> `c list

这个功能很简单:

fun absProdList f ls =
    case l of 
        [] => []
      | (x,y) :: ls' => (f (x,y)) :: (absProdList f ls')

这个函数是addList你提到的函数的超类型。只需定义一个匿名函数来重新创建您的addListas :

fun addList' ls =
    absProdList (fn (x,y) => x + y) ls

如您所见,定义泛型类型函数可以通过适当组合以下方式对作为通用类型替换的函数进行特定调用更容易和更优雅:Currying、高阶函数和匿名函数。

于 2017-08-14T00:26:30.543 回答
0

您可能不想要一个int list list作为输入,而只是一个int list * int list(一对 int 列表)。除此之外,您的函数似乎返回数字而不是数字列表。为此,您将使用递归。

fun listAdd (x::xs, y::ys) = (x + y) :: listAdd (xs, ys)
  | listAdd ([], _) = []
  | listAdd (_, []) = [] (* The last two cases can be merged *)

您可能想从第一页开始阅读有关函数式编程的书。如果您想要免费的,请选择 Riccardo Pucella的《SML/NJ 编程笔记》 。

于 2013-09-13T18:39:01.313 回答