scala 如何为Int添加自定义半群示例

dw1jzc5e  于 2023-05-17  发布在  Scala
关注(0)|答案(1)|浏览(103)
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工作?

3pmvbmvn

3pmvbmvn1#

导入Semigroup[Int]的两个示例:
1.通过import cats.implicits._
1.通过import SemigroupInstances._
编译器选择cats.implicits._中的一个,而不是您的自定义示例。
如果删除该导入,它将工作:https://scastie.scala-lang.org/avsmEturTRGkNEOCDxuXOA
如果你想了解更多关于编译器如何选择使用哪个隐式示例的信息,请参阅这篇文章:Scala在哪里寻找隐式?
在您的特定情况下,原因似乎是cats示例的类型实际上是CommutativeGroup[Int]

implicit val catsKernelStdGroupForInt: CommutativeGroup[Int] = new IntGroup

因此,作为一个派生类(CommutativeGroup扩展了Semigroup),它被认为更具体,因此是首选的。
如果将示例的类型更改为CommutativeGroup[Int](这在数学上是不正确的,但这不是重点),则会出现“Ambiguous given instances”错误,因为编译器无法决定使用哪个示例:https://scastie.scala-lang.org/dzClDOYDSJ20P1SRpH72nA

相关问题