Search code examples
scalacontravariance

Why passing Int => Int to a function taking AnyVal => Int results in type mismatch when Int extends AnyVal?


I'm new to scala and I'm having some hard time with passing a func as a parameter to a different func. The function that I'm trying to pass should get an argument but I dont know its type (but its a value defenitly):

object Sing
    def myFunc(myinnerfunc:(AnyVal)=>Int):Anyval
    {
    ...
    }

object main {
  def main(args : Array[String]): Unit ={
    val a = Sing.myFunc((x:Int)=>2*x:Int)
  }
}

The error I'm getting is :

type mismatch : 
found : (Int)=>Int
required : (AnyVal)=>Int

Solution

  • Despite the fact that Int extends AnyVal, the function myFunc cannot accept Int => Int because in Scala function is

    contravariant over its argument type, and covariant over its return type

    which means Int => Int is not a subtype of AnyVal => Int

    implicitly[(Int => Int) <:< (AnyVal => Int)]   // Error: Cannot prove
    

    If you know the function argument is of numeric type, then consider Numeric typeclass solution

    def myFunc[T](myinnerfunc: T => Int)(implicit num: Numeric[T]): T = ???