Тип возврата с типом класса, но без другой информации о типе - PullRequest
0 голосов
/ 12 июня 2018

Допустим, у меня есть некоторый класс типов:

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, которое решает эту проблему?

1 Ответ

0 голосов
/ 12 июня 2018

Поскольку ваш метод действительно должен возвращать 3 или 1,0 в зависимости от какого-либо условия, и эта часть не может быть изменена, тогда вам обязательно нужен тип суммы для возвращаемого типа.

Это может быть смоделировано либо с помощью общего суперкласса, который вы выбрали, либо с помощью непересекающихся объединений, таких как Either, scalaz.\/ и т. Д., В этом случае вы должны вернуть, например, Int \/ Double.Если есть много потенциальных типов, которые могут появиться, то вам понадобится «либо из либо, либо», либо (гораздо более удобный) бесформенный HList , либо просто придерживаться суперкласса Greetable.

Я думаю, что неясность этой ситуации проистекает не из решения, а из самой проблемы.Метод, который возвращает два или более различных типа, основанных на некоторой внутренней логике, на самом деле не сам FP, не так ли?:)

...