2016-08-07 1 views
0

Я учусь Scala и следующая простая программа заставили меня застряли:Missing параметра типа для расширенной функции

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); 
} 

Сообщение об ошибке выглядит следующим образом:

Отсутствующего параметр типа для расширенной функции. Тип аргумента анонимной функции должен быть полностью известен. Ожидаемый тип:?

Сообщение совершенно неясно. Что они означают, отсутствующий параметр типа? Я думал, что параметр типа следует за case, например Is(i). Какая функция расширена?

UPD: Я хочу вернуть функцию в зависимости от типа аргумента, переданного в качестве параметра.

+2

'def print (t: T) = t match {...}'? В настоящее время ваш метод возвращает анонимную функцию, а 't' не используется. –

ответ

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

короток для

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

(это расширенная функции ошибка говорит. Но компилятор не имеет никакого способа, чтобы сказать, что вы хотите y «s типа будет.

Если это то, что вы хотите, самый простой способ определить тип будет

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

Но это выглядит довольно странно: вы не используете ни x, ни t.

2

Я бы реализовать через класс типов

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 
} 

С другой стороны, это один - компилирует

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); 
} 

(хотя я не вижу USECASE, как вы будете использовать печать, то почему Вы поддерживаете t и x такого же типа)

Может быть, у вас должна быть такая реализация:

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)) 
}