SML / NJ新手。从列表列表中添加数字

时间:2013-09-13 17:38:27

标签: functional-programming sml smlnj

  

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

我是函数式编程的新手,并且在使用SML时遇到了正确的语法问题。为了解决这个问题,我尝试使用模式匹配创建一个函数,只需添加列表的前两个元素。在我开始工作之后,我将使用递归来添加其余元素。虽然,我甚至似乎无法编译这个简单的函数。

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

3 个答案:

答案 0 :(得分:2)

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

应该做你想要的样子。

此外,看起来您的函数问题的一部分是您在不同的子句中为函数提供不同的名称(listAdd和listAnd)。

答案 1 :(得分: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为例Notes on Programming in SML/NJ

答案 2 :(得分:0)

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

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

现在,我只是将其定义为解压缩函数的抽象:

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函数的超类型。只需定义匿名函数即可将addList重新创建为:

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

正如您所看到的,定义泛型类型函数通过适当组合:Currying,高阶函数和匿名函数,使对特定类型替换的函数的特定调用更容易,更优雅。