Adding two Set[Any]
Asked Answered
F

4

8

Adding two Set[Int] works:

Welcome to Scala version 2.8.1.final (Java HotSpot(TM) Server VM, Java 1.6.0_23).
Type in expressions to have them evaluated.
Type :help for more information.

scala> Set(1,2,3) ++ Set(4,5,6)          
res0: scala.collection.immutable.Set[Int] = Set(4, 5, 6, 1, 2, 3)

But adding two Set[Any] doesn't:

scala> Set[Any](1,2,3) ++ Set[Any](4,5,6)
<console>:6: error: ambiguous reference to overloaded definition,
both method ++ in trait Addable of type (xs: scala.collection.TraversableOnce[Any])scala.collection.immutable.Set[Any]
and  method ++ in trait TraversableLike of type [B >: Any,That](that: scala.collection.TraversableOnce[B])(implicit bf: scala.collection.generic.CanBuildFrom[scala.collection.immutable.Set[Any],B,That])That
match argument types (scala.collection.immutable.Set[Any])
   Set[Any](1,2,3) ++ Set[Any](4,5,6)
           ^

Any suggestion to work around this error?

Flapper answered 6/1, 2011 at 21:39 Comment(1)
It was fixed in scala2.9. Addable was removed. See [ticket4059][lampsvn.epfl.ch/trac/scala/ticket/4059] for more information.Twinflower
O
5

This works:

Set[Any](1, 2, 3).++[Any, Set[Any]](Set[Any](4, 5, 6))

But is ugly as sin. The compiler is confused as to whether to use the method on Addable or the one on TraversableLike, which has an implicit parameter. They don't have the same sig, but syntactic sugar makes it appears as if they do. Tell it which one to use and the compiler's happy.

I imagine the reason it works for Ints is that they don't have any subtypes.

This will call the method on Addable, if that's important to you:

Set[Any](1, 2, 3).asInstanceOf[collection.generic.Addable[Any, Set[Any]]] ++ Set[Any](4, 5, 6)
Overstretch answered 6/1, 2011 at 21:52 Comment(1)
@Landei: You're right. The value's a Set, but it would have to be cast. That's interesting.Overstretch
F
13

Looks like using the alias union works,

scala> Set[Any](1,2,3) union Set[Any](4,5,6)
res0: scala.collection.immutable.Set[Any] = Set(4, 5, 6, 1, 2, 3)

I'm still curious if there's a way to use ++ instead.

Flapper answered 6/1, 2011 at 21:45 Comment(0)
O
5

This works:

Set[Any](1, 2, 3).++[Any, Set[Any]](Set[Any](4, 5, 6))

But is ugly as sin. The compiler is confused as to whether to use the method on Addable or the one on TraversableLike, which has an implicit parameter. They don't have the same sig, but syntactic sugar makes it appears as if they do. Tell it which one to use and the compiler's happy.

I imagine the reason it works for Ints is that they don't have any subtypes.

This will call the method on Addable, if that's important to you:

Set[Any](1, 2, 3).asInstanceOf[collection.generic.Addable[Any, Set[Any]]] ++ Set[Any](4, 5, 6)
Overstretch answered 6/1, 2011 at 21:52 Comment(1)
@Landei: You're right. The value's a Set, but it would have to be cast. That's interesting.Overstretch
B
3

That works, but won't win the "Beautiful Code Contest":

Set[Any](1,2,3).++[Any,Set[Any]](Set[Any](4,5,6))
Blakley answered 6/1, 2011 at 21:55 Comment(0)
A
3
val s:scala.collection.TraversableLike[Any, Set[Any]] = Set(1,2,3)
val t:Set[Any] = Set(3,4,5)
s ++ t

Consider this yet another entry in the ugliest code contest. ;)

Andreandrea answered 6/1, 2011 at 22:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.