KyBe
KyBe

Reputation: 842

Why if for V <: Seq[Int] when V is a Seq descendant map and zip operations return a Seq[Int]

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

Answers (2)

Nhan Trinh
Nhan Trinh

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

Alexey Romanov
Alexey Romanov

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

Related Questions