Reputation: 7
I'm very new to SML and I need help with this problem,
What I'm trying to do is, I have a list of tuples of int * int and the output is a list where the elements of the tuples are added up, like this:
[(1,2),(3,4)...] = [3,7,....]
This is the code I did for this, but I have an error that I don't know how to solve
fun sumpares [] = []
| sumpares [(x,y)] = [x+y]
| sumpares ((x,y)::xs) = [x+y]::sumpares(xs)
This is the error:
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
How can I fix it? Also, is there a way to do this if you have lists instead of tuples
Upvotes: 0
Views: 537
Reputation: 36536
Consider your sumpares
function. If we give it an empty list, it returns an empty list. That's easy.
In the next case, we feed it an (int * int) list
and we get an int list
in return. So far the type of sumpares
is (int * int) list -> int list
. But now consider the next case.
((x,y)::xs)
does match an (int * int) list
but then you return: [x+y]::sumpares(xs)
. An int list
cannot be added to the front of an int list
using ::
. This would only work if sumpares(xs)
returned an int list list
.
There are a few ways to fix this.
First, there is no need for the second case with a single tuple at all. Let's get rid of that.
fun sumpares [] = []
| sumpares ((x,y)::xs) = [x+y]::sumpares(xs)
This actually will compile because []
is an int list list
, but an int list list
is not what you're looking for. To get the desired result...
We could use the @
operator to concatenate the two lists.
fun sumpares [] = []
| sumpares ((x,y)::xs) = [x+y] @ sumpares(xs)
But this is much less efficient than just constructing a list by tacking x+y
onto the front of the list created by the recursive call.
fun sumpares [] = []
| sumpares ((x,y)::xs) = (x+y) :: sumpares(xs)
It may also be useful to realize that what you're doing is reimplementing a very specific use of map
.
val sumpares = map op+
You can definitely see this by looping at a simple implementation of map
.
fun map _ [] = []
| map f (x::xs) = f x :: map f xs
Upvotes: 2