简体   繁体   中英

Missing type parameter for expanded function

I'm learning Scala and the following simple program got me stuck:

class ObjectPrinter[T <: AnyVal](x: T) {
  def print(t: T) = { // <--- error here
    case Is(i) => println("Integer: " + i)
    case Ds(d) => println("Double: " + d)
    case _ => println("Default")
  }

  case class Is(i : Int) extends ObjectPrinter[Int](i);
  case class Ds(d: Double) extends ObjectPrinter[Double](d);
}

The error message is the following:

Missing type parameter for expanded function. The argument type of an anonymous function must be fully known. Expected type was: ?

The message is completely unclear to me. What do they mean, missing type parameter? I thought the type parameter follows after the case , like Is(i) . What function is expanded?

UPD: I want to return a function depending on the type of the argument passed in as a parameter.

{
  case Is(i) => println("Integer: " + i)
  case Ds(d) => println("Double: " + d)
  case _ => println("Default")
}

is short for

y => y match {
  case Is(i) => println("Integer: " + i)
  case Ds(d) => println("Double: " + d)
  case _ => println("Default")
}

(that's the expanded function the error is talking about. But the compiler has no way to tell what do you want y 's type to be.

If this is what you want, the simplest way to specify the type would be

(_: SomeType) match {
  case Is(i) => println("Integer: " + i)
  case Ds(d) => println("Double: " + d)
  case _ => println("Default")
}

But this looks quite strange: you are using neither x nor t there.

I would implement it through typeclass

case class ObjectPrinter[T <: AnyVal](x: T)

object ObjectPrinter {
  implicit val printInt = new Print[Int] {
    override def print(t: ObjectPrinter[Int]): Unit = println("Integer: " + t.x)
  }

  implicit val printDouble = new Print[Double] {
    override def print(t: ObjectPrinter[Double]): Unit = println("Double: " + t.x)
  }

  def print[T <: AnyVal](t: ObjectPrinter[T])(implicit print: Print[T]) = {
    print.print(t)
  }
}

trait Print[T <: AnyVal] {
  def print(t: ObjectPrinter[T]): Unit
}

Alternatively, this one - compiles

class ObjectPrinter[T <: AnyVal](x: T) {
  def print(t: T): Unit = t match { 
    case i: Int => println("Integer: " + i)
    case d: Double => println("Double: " + d)
    case _ => println("Default")
  }

  case class Is(i : Int) extends ObjectPrinter[Int](i);
  case class Ds(d: Double) extends ObjectPrinter[Double](d);
}

(though I do not see any usecase how you would use print, ie why do you enforce t and x be the same type)

May be you meant to have such implementation:

class ObjectPrinter[T <: AnyVal](x: T) 

object ObjectPrinter {
  def print[T <: AnyVal](op: ObjectPrinter[T]): Unit = op match { // <--- error here
    case Is(i: Int) => println("Integer: " + i)
    case Ds(d: Double) => println("Double: " + d)
    case _ => println("Default")
  }

}

case class Is(i : Int) extends ObjectPrinter[Int](i)
case class Ds(d: Double) extends ObjectPrinter[Double](d)

object Test extends App {
  ObjectPrinter.print(Is(5))
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM