Julio
Julio

Reputation: 718

Scala type bounds =:=

While this compiles:

  implicit class Container[T](val value:T) extends AnyVal{
    def addInt(x:Int)(implicit ev:T=:=Int) = value+x
  }

This complains about type mismatch, expected T, actual Int, as if it ignores the type bound.

  implicit class Container[T](val value:T=>Int) extends AnyVal{
    def addInt(x:Int)(implicit ev:T=:=Int) = value(x)
  }

Why?

Upvotes: 0

Views: 105

Answers (2)

Michael Zajac
Michael Zajac

Reputation: 55569

Your type constraint is backwards, actually. T =:= Int provides implicit evidence that T is Int, but not exactly that Int is T. If you look at the declaration if =:=, you'll see that it only goes one way:

sealed abstract class =:=[From, To] extends (From => To) with Serializable

Your first example works because value is a T, and the constraint is T =:= Int, which implicitly converts T to Int. But for the second example, we need to feed a T to value: T => Int, so we need the other direction.

This works:

implicit class Container[T](val value: T => Int) extends AnyVal {
    def addInt(x: Int)(implicit ev: Int =:= T) = value(x)
}

The reason why your second example using Int <:< T also works is because <:< provides the implicit conversion from Int => T.

Upvotes: 2

Julio
Julio

Reputation: 718

Oh probably the issue is the contra-variance of the function. This works now:

implicit class Container[T](val value:T=>Int) extends AnyVal{
    def addInt(x:Int)(implicit ev:Int<:<T) = value(x)
  }

Upvotes: 0

Related Questions