Reputation: 842
As mentioned in the title i don't understand why these function doesn't compile and are asking for a Seq.
def f1[V <: Seq[Int]](v: V): V = v.map(_ + 1)
def f2[V <: Seq[Int]](v: V): V = v.zip(v).map{ case (a, b) => a + b }
error: type mismatch;
found : Seq[Int]
required: V
I have the following workaround :
def f1[V <: Seq[Int]](v: V): V = v.map(_ + 1).asInstanceOf[V]
def f2[V <: Seq[Int]](v: V): V = v.zip(v).map{ case (a, b) => a + b }.asInstanceOf[V]
But i would like to know if it exist another solution. If not what is the cost of casting something like that, is it O(1) or O(n) with n the Seq size.
Upvotes: 3
Views: 62
Reputation: 191
Let's go through how your function is compiled:
def f1[V <: Seq[Int]](v: V): V = v.map(_ + 1)
1/ You declared V
as a sub-type of Seq[Int]
. So V
can be viewed by the compiler as Seq[Int]
.
2/ Inside function, v.map(_ + 1)
return type is Seq[Int]
because it's using a Seq
method.
3/ V
is the declared return type. This doesn't match the actual return type, which is Seq[Int]
. And your compiler can't view Seq[Int]
as V
because because there's no type bound that says [V >: Seq[Int]]
.
Upvotes: 1
Reputation: 170775
Because
v.map(_ + 1).asInstanceOf[V]
can easily fail: map
is only guaranteed to return a Seq[Int]
, which may or may not happen to be an instance of V
when you run the code.
One example would be V = SeqView.Filtered
, where map
returns a SeqView.Mapped
.
If not what is the cost of casting something like that, is it O(1) or O(n) with n the Seq size.
The cost of casting with asInstanceOf
is always O(1). In some cases it's actually a no-op and the cost is 0.
Upvotes: 2