Как scala обрабатывает неявные классы типов без создания экземпляра члена? - PullRequest
0 голосов
/ 27 февраля 2020

Я замечаю, что когда я пытаюсь создать экземпляр fooSemigroup, в первой версии анонимная функция создает экземпляр fooSemigroup без создания экземпляра члена Foo, но когда я пытаюсь сделать это без конструкции SAM, мне нужно создать фиктивный экземпляр foo для SemigroupOps, чтобы получить неявное значение ev.

trait Semigroup[A] {
  def combine(x: A, y: A): A
}
case class Foo(v: Int)

// vs 1
implicit val fooSemigroup: Semigroup[Foo] = (x: Foo, y: Foo) => Foo(x.v + y.v)

// vs 2
class fooSemigroup(foo: Foo) extends Semigroup[Foo] {
  def combine(x: Foo, y: Foo) = Foo(x.v + y.v)
}
implicit val f: fooSemigroup = Foo(0)

implicit class SemigroupOps[A](x: A) {
  def +(y: A)(implicit ev: Semigroup[A]): A = ev.combine(x, y)
}

1 Ответ

4 голосов
/ 27 февраля 2020

Вместо неявного класса

implicit class fooSemigroup(foo: Foo) extends Semigroup[Foo] {
  def combine(x: Foo, y: Foo) = Foo(x.v + y.v)
}

попробуйте неявный объект

implicit object fooSemigroup extends Semigroup[Foo] {
  def combine(x: Foo, y: Foo) = Foo(x.v + y.v)
}

Однако, согласно совету Луиса, отдавайте предпочтение implicit val экземплярам над implicit object, иначе разрешение может привести к ambiguous implicit values ошибка, например

trait SomeTrait[T] {
  def f: T
}
trait ExtendedTrait[T] extends SomeTrait[T] {
  def g: T
}
implicit object SomeStringObject extends SomeTrait[String] {
  override def f: String = "from object f"
}
implicit object ExtendedStringObject extends ExtendedTrait[String] {
  override def f: String = "from extended obj f"
  override def g: String = "from extended obj g"
}

implicitly[SomeTrait[String]] // Error: ambiguous implicit values

, где полная ошибка состояния

Error:(15, 77) ambiguous implicit values:
 both object ExtendedStringObject in class A$A7 of type A$A7.this.ExtendedStringObject.type
 and object SomeStringObject in class A$A7 of type A$A7.this.SomeStringObject.type
 match expected type A$A7.this.SomeTrait[String]
def get$$instance$$res0 = /* ###worksheet### generated $$end$$ */ implicitly[SomeTrait[String]];}
                                                                            ^
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...