import cats._
import cats.implicits._
object SemigroupInstances {
implicit val intSemigroup: Semigroup[Int] = new Semigroup[Int] {
override def combine(a: Int, b: Int) = a * b
}
}
import SemigroupInstances._
object Semigroup {
def apply[T](implicit instance: Semigroup[T]): Semigroup[T] = instance
}
val intSemigroup = Semigroup[Int]
intSemigroup.combine(4, 4) // expected 16, actual 8
那么,如何使自定义intSemigroup
工作?
1条答案
按热度按时间3pmvbmvn1#
导入
Semigroup[Int]
的两个示例:1.通过
import cats.implicits._
1.通过
import SemigroupInstances._
编译器选择
cats.implicits._
中的一个,而不是您的自定义示例。如果删除该导入,它将工作:https://scastie.scala-lang.org/avsmEturTRGkNEOCDxuXOA
如果你想了解更多关于编译器如何选择使用哪个隐式示例的信息,请参阅这篇文章:Scala在哪里寻找隐式?
在您的特定情况下,原因似乎是cats示例的类型实际上是
CommutativeGroup[Int]
:因此,作为一个派生类(
CommutativeGroup
扩展了Semigroup
),它被认为更具体,因此是首选的。如果将示例的类型更改为
CommutativeGroup[Int]
(这在数学上是不正确的,但这不是重点),则会出现“Ambiguous given instances”错误,因为编译器无法决定使用哪个示例:https://scastie.scala-lang.org/dzClDOYDSJ20P1SRpH72nA