Reputation: 718
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
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
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