0

I have the following simple wrapper class and an implicit converter to automatically wrap values:

import scala.language.implicitConversions

case class Wrap[T](t: T)

implicit def autoWrap[T](t: T): Wrap[T] = Wrap(t)

This works fine mostly:

scala> val w: Wrap[_] = 5
w: Wrap[_] = Wrap(5)

scala> val w: Wrap[_] = Set(1,2,3)
w: Wrap[_] = Wrap(Set(1, 2, 3))

Except for in this one instance:

scala> val w: Wrap[_] = Seq(1,2,3).toSet
<console>:15: error: polymorphic expression cannot be instantiated to expected type;
 found   : [B >: Int]scala.collection.immutable.Set[B]
 required: Wrap[_]
       val w: Wrap[_] = Seq(1,2,3).toSet
                               ^

If I assign the value first, it also works:

scala> Seq(1,2,3).toSet
res1: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

scala> val w: Wrap[_] = res1
w: Wrap[_] = Wrap(Set(1, 2, 3))

What's going on here?

Alfredo Gimenez
  • 2,174
  • 1
  • 14
  • 19
  • 1
    This is at the hairy interface between subtyping and type inference. You can solve this particular problem by throwing in a type parameter to `toSet`: `val w: Wrap[_] = Seq(1,2,3).toSet[Int]` – Alec Oct 10 '16 at 23:55
  • Interesting, it seems like the compiler would be able to infer the return type of `toSet`. Also oddly enough, the problem doesn't occur with `toSeq`, e.g. `val w: Wrap[_] = Set(1,2,3).toSeq`. Does it have to do with the implementation of `Set` as a function? – Alfredo Gimenez Oct 11 '16 at 16:59
  • Not quite. The problem really still is subtyping: `def toSeq: Seq[A]` doesn't have any subtyping going on, but `def toSet[B >: A]: immutable.Set[B]` does. If you made your own `def toSet2[A]: immutable.Set[A]` (that called the other `toSet` under the hood) I wager `val w: Wrap[_] = Seq(1,2,3).toSet2` would work. – Alec Oct 11 '16 at 17:07
  • Ah I see. So why *does* `toSet` return a `Set[B >: A]` instead of just a `Set[A]`? – Alfredo Gimenez Oct 11 '16 at 17:15
  • 1
    @Alec Found my answer here http://stackoverflow.com/a/5545067/2275672 and here http://stackoverflow.com/questions/676615/why-is-scalas-immutable-set-not-covariant-in-its-type – Alfredo Gimenez Oct 11 '16 at 17:26
  • Yeah. That part of the standard libraries could perhaps have been done better. :S By the way, with respect to your original question, if you _really_ want to figure out what is going on, you'll have to go digging through the [Scala Specification](http://www.scala-lang.org/files/archive/spec/2.11/). – Alec Oct 11 '16 at 17:33

0 Answers0