smlnj-在Int列表中添加偶数和奇数元素的函数

时间:2018-10-04 03:56:33

标签: functional-programming sml smlnj ml

我对函数式编程相当陌生,在这里我不理解我的错误。我试图使一个函数,它接受一个整数列表,并返回偶数元素的总和和奇数元素的总和。我得到的错误在第1行中,它指出:“错误:子句的右侧与函数结果类型[过载冲突] ...不符。”。我不了解该错误,希望能帮助您理解我的错误。

fun add(nil) = 0
|   add([x]) = x
|   add(x :: xs) =
        let
            val evenList = xs;
            val oddList = x :: xs
        in
            (hd evenList + add(tl(tl(evenList))), hd oddList + add(tl(tl(oddList))))
        end;

1 个答案:

答案 0 :(得分:2)

类型错误的原因是该函数应该返回一个对,但是您的基本情况却没有。

我怀疑您是通过考虑跳过其他所有元素,然后通过跳过列表划分来获得该代码的。

有另一种方法可以解决这个问题。

考虑列表[a,b,c,d]

从1开始计数,元素已编号

1 2 3 4
a b c d

现在考虑一下列表尾部的位置。
他们是

1 2 3
b c d

也就是说,尾部的奇数位置在整个列表中是偶数位置,尾部的偶数位置在整个列表中是奇数。

这意味着,如果我们递归地计算尾部的“奇数和偶数”,我们将从尾部得到总和,其中“奇数”是我们的“偶数”,并且如果将头部加到尾部的“偶数”中”,我们将获得所需的“赔率”。

我们现在所需要的只是一个很好的基本案例–空列表的总和必须为(0, 0)

类似这样的东西:

fun add [] = (0,0)
  | add (x::xs) = case add xs of
                      (odds, evens) => (x + evens, odds)

或者,您可以使用let绑定而不是case来解构递归结果:

fun add [] = (0,0)
  | add (x::xs) = let val (odds, evens) = add xs
                   in
                       (x + evens, odds)
                   end