SML - Error: operator and operand do not agree [overload - bad instantiation]

SML - Error: operator and operand do not agree [overload - bad instantiation]

我是 SML 的新手,我需要帮助解决这个问题,

我想做的是,我有一个 int * int 元组列表,输出是一个列表,其中元组的元素相加,如下所示:

[(1,2),(3,4)...] = [3,7,....]

这是我为此做的代码,但我有一个错误,我不知道如何解决

fun sumpares [] = []
  | sumpares [(x,y)] = [x+y]
  | sumpares ((x,y)::xs) = [x+y]::sumpares(xs)

这是错误:

stdIn:68.28-68.47 Error: operator and operand do not agree [overload - bad instantiation]
  operator domain: 'Z[OL(+,+)] list * 'Z[OL(+,+)] list list
  operand:         'Z[OL(+,+)] list * 'Z[OL(+,+)] list
  in expression:
    (x + y :: nil) :: sumpares xs

我该如何解决?另外,如果你有列表而不是元组,有没有办法做到这一点

考虑一下您的 sumpares 功能。如果我们给它一个空列表,它 return 就是一个空列表。很简单。

在下一种情况下,我们给它一个 (int * int) list,然后我们在 return 中得到一个 int list。到目前为止 sumpares 的类型是 (int * int) list -> int list。但是现在考虑下一个案例。

((x,y)::xs) 确实匹配 (int * int) list 但是 然后你 return: [x+y]::sumpares(xs)。不能使用 ::int list 添加到 int list 的前面。这仅在 sumpares(xs) returned 一个 int list list.

时有效

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

首先,第二种情况根本不需要单个元组。让我们摆脱它。

fun sumpares [] = []
  | sumpares ((x,y)::xs) = [x+y]::sumpares(xs)

这实际上可以编译,因为 [] 是一个 int list list,但 int list list 不是您要找的。为了得到想要的结果...

我们可以使用 @ 运算符连接两个列表。

fun sumpares [] = []
  | sumpares ((x,y)::xs) = [x+y] @ sumpares(xs)

但这比通过将 x+y 附加到递归调用创建的列表的前面来构建列表效率要低得多。

fun sumpares [] = []
  | sumpares ((x,y)::xs) = (x+y) :: sumpares(xs)

意识到您正在做的是重新实现 map.

的一个非常具体的用途可能也很有用
val sumpares = map op+

你可以通过在 map.

的简单实现中循环来明确地看到这一点
fun map _ [] = []
  | map f (x::xs) = f x :: map f xs