14

Is there a easy way to add tuples which contain addable elements like Int, Doubles etc? For examples,

(1,2) + (1,3) = (2,5)
4
  • what are you trying to achieve? mostly using tuples for such thing (might be) considered bad style. Commented Oct 26, 2013 at 14:03
  • tuples aren't intended for this type of thing. They're just a convenient wrapper for methods that return multiple values, which is why they don't have a host of useful functions like collections do. Commented Oct 26, 2013 at 14:31
  • 1
    I was trying to reduce a list of tuples. I am using tuples to do some map reduce type operations. Customs classes and objects seems overkill. Commented Oct 26, 2013 at 15:24
  • @Arun, if you are working with lists of tuples you might find (my) project github.com/marklister/product-collections useful. Commented Oct 27, 2013 at 9:11

3 Answers 3

20

Scalaz

import scalaz._, Scalaz._

scala> (1, 2.5) |+| (3, 4.4)
res0: (Int, Double) = (4,6.9)

There is an operator |+| for any class A with implicit Semigroup[A] in scope. For Int |+| is + by default (you could redefine it in your code).

There is an implicit Semigroup[(A, B)] for all tuples if there is implicit Semigroup for A and B.

See Scalaz cheat sheet.

Sign up to request clarification or add additional context in comments.

Comments

13

+1 for the the Scalaz answer :-)

If you want a very simple version of it you could define an implicit class like:

implicit class TuppleAdd(t: (Int, Int)) {
  def +(p: (Int, Int)) = (p._1 + t._1, p._2 + t._2)
}

(1, 1) + (2, 2) == (3, 3)

// update1, more generic version for numbers:

So this is the simplest version, defined only for Ints, we could generify it for all numeric values using Scala's Numeric:

implicit class Tupple2Add[A : Numeric, B : Numeric](t: (A, B)) {
  import Numeric.Implicits._

  def + (p: (A, B)) = (p._1 + t._1, p._2 + t._2)
}

(2.0, 1) + (1.0, 2) == (3.0, 3)

4 Comments

There is not only Int in the question. You could improve your answer with math.Numeric like this: implicit class TuppleAdd[A : Numeric, B : Numeric](t: (A, B)) { import Numeric.Implicits._; def +(p: (A, B)) = (p._1 + t._1, p._2 + t._2) }.
That is true :-) I also thought about a version with a structural type, but let's not go there maybe ;-)
I've also tried to implement implicit def tupleIsNumeric[A : Numeric, B : Numeric]: Numeric[(A, B)], but there is an issue with + operator (- and * works fine).
Does your + issue perchance have to do with this?: stackoverflow.com/questions/6906742/…
1

This works with Cats as well, and similar to the scalaz answer:

> (1,2) |+| (1,3)
res3: (Int, Int) = (2, 5)

And likewise, it relies on Semigroup.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.