Missing parameter type error

scala

underscore expanding / parameters in the same group/ function overloading / generic function

This error typically could be fixed by adding the concrete type. It’s caused by the limitation of scala’s type inference system. The algorithm is not that smart to infer every case considering the analysis time required. There are 4 common cases which will incur this kind of error.

underscore expanding

object MissingType {

  def main(args: Array[String]): Unit = {
    // missing parameter type for expanded function
    List(1, 2, 3).map(_ + _)
  }
}

Each underscore will be expanded to one parameter. Two _ will be treated as two parameters. But map only accepts one argument function. Updating the code to List(1, 2, 3).map(x => x + x) to fix.

parameters in the same group

object MissingType {

  def combine[T](list: List[T], f: (T, T) => T): T = {
    list.reduce(f)
  }

  def main(args: Array[String]): Unit = {
    // error: missing parameter type
    combine(List(1, 2, 3), (a, b) => a + b)
  }
}

f and list are in the same parameter group. Though list is List[Int], the type info cannot be used by f. As the type info flows from one parameter group to another but not for the same group. It can be fixed by put f into the second parameter list like:

  def combine[T](list: List[T])(f: (T, T) => T): T = {
    list.reduce(f)
  }

function overloading

object MissingType {

  def f[A, B](b: B, g: B => A): A = {
    g(b)
  }

  def f[A, B](list: List[B], g: B => A): List[A] = {
    list.map(g)
  }

  def main(args: Array[String]): Unit = {
    // error: missing parameter type
    f[Int, Int](List(1, 2, 3), a => a * 2)
  }
}

This error is due to function overloading of f. It’s hard for compiler to infer the types at this case. It requires programmer to specify types manually. Fixed it by call it like f[Int, Int](List(1, 2, 3), (a: Int) => a * 2).

generic function

def put[T](key: String, value: T): KVStore[Unit] = ???

def get[T](key: String): KVStore[T] = ???

def update[T](key: String, f: T => T): KVStore[Unit] = ???

put("a", 1) // Int can be inferred from 1, so it can be omitted
get[Int]("a") // missing parameter error if without [Int], coz no type info if not specified
update[Int]("a", _ + 1) // missing parameter error if without [Int], coz no type info of the underscore