Допустим, у меня есть некоторый класс типов:
trait Greeter[A] {
def greet(a: A): String
}
И я хочу написать метод, который возвращает значения, для которых существует экземпляр этого класса типов:
implicit val intGreeter = new Greeter[Int] {
def greet(n: Int): String = s"Hello, integer $n!"
}
implicit val doubleGreeter = new Greeter[Double] {
def greet(d: Double): String = s"Hello, double $d"
}
def foo(b: Boolean): <X> = {
if (b) 3 else 1.0
}
Где <X>
это некоторая сигнатура типа.А затем используйте что-то вроде:
val g: <X> = foo(true)
println(implicitly[Greeter[<X>]].greet(g))
Конечно, это не работает напрямую.Я мог бы сделать что-то вроде этого:
trait Greetable {
def greet: String
}
def getGreetable[A : Greeter](a: A) = new Greetable {
def greet: String = implicitly[Greeter[A]].greet(a)
}
def foo(b: Boolean): Greetable = {
if (b) getGreetable(3) else getGreetable(1.0)
}
Это работает просто отлично, но кажется немного неудобным и не очень расширяемым.Я должен определить соответствующую черту для каждого класса типов.А что, если я хочу получить возвращаемый тип, у которого есть экземпляры для двух классов типов?Или п?Это также похоже на ОО-подход;есть что-то из мира FP, которое решает эту проблему?