Scala неявный def, возвращающий A с B - PullRequest
0 голосов
/ 21 февраля 2019

Я бился головой об этом и не могу понять, есть ли способ сделать это правильно.Я чувствую, что знаю, в чем проблема, но не знаю, как ее решить.

У меня есть метод:

implicit def combineAlg[A: Alg, B: Alg]: Alg[A with B] = ...

, если я вызываю его явно, он работает нормально, однаконикогда не подразумевается должным образом.

// works
implicit val comb: Alg[A with B] = combineAlg[A, B]

// doesn't work
implicit val comb: Alg[A with B] = implicitly[Alg[A with B]]

Благодаря моей отладке с -Xlog-implicits, я считаю, что его вызов combineAlg[A with B, Nothing].

Я ищу способ сделать что-то вроде:

implicit def combineExpAlg[AB, A >: AB, B >: AB]

или

implicit def combineExpAlg[AB, A, B](implicit ev1: AB <:< A, ev2: AB <:< B)

, так что он понимает, что ему нужно разделить "с", но не помогает.

Не уверен, что естьспособ сделать это, на самом деле это эксперимент, который я делаю для "объектных алгебр" в Scala и пытаюсь понять, как удалить шаблон.

Было бы замечательно, если бы было решение.Дотти-решение также было бы приемлемо, так как я также реализую его там, чтобы посмотреть, не упростят ли некоторые из новых функций.

В случае, если требуется дополнительная информация, вы можете просмотреть репозиторий здесь Я пытаюсь изменить это algebra.combineExpAlg.Похоже, что это работает, потому что я определяю конкретные последствия в algebra.interpreters.package, в которых конкретно прописана каждая пара интерпретаторов, что я и пытаюсь обобщить.

1 Ответ

0 голосов
/ 21 февраля 2019

Компилируется следующий код:

  trait Alg[T]

  trait LowPriorityAlg {
    implicit def bAlg: Alg[B0] =  ???
  }
  object Alg extends LowPriorityAlg {
    implicit def aAlg: Alg[A0] =  ???
    implicit def combineAlg[AB, A: Alg, B: Alg](implicit ev1: AB <:< A, ev2: AB <:< B): Alg[AB] = ???    
  }

  trait A0
  trait B0

  val comb: Alg[A0 with B0] = Alg.combineAlg[A0 with B0, A0, B0]

  val comb1: Alg[A0 with B0] = implicitly[Alg[A0 with B0]]
...