【发布时间】:2021-11-21 15:09:45
【问题描述】:
我在 scala 中玩猫的 Monoid,当时我看到 Monoid 操作以自然的方式扩展到 Tuples:
import cats.Monoid
object mon {
implicit object IntMonoid extends Monoid[Int] {
def combine(a: Int, b: Int) = a*a + b*b
def empty = 0
}
implicit object ListMonoid extends Monoid[List[Int]] {
def combine(a: List[Int], b: List[Int]): List[Int] =
a.zip(b).map(z => z._1 * z._2)
def empty = List(1)
}
def comb[T](a: T, b: T)(implicit m: Monoid[T]) =
m.combine(a, b)
}
val list1 = List(1, 2, 3)
val list2 = List(2, 3, 4)
println(mon.comb(list1, list2)) // outputs: List(2, 6, 12) as expected
val int1 = 2
val int2 = 4
println(mon.comb(int1, int2)) // outputs: 20 as expected
val x = (list1, int1)
val y = (list2, int2)
println(mon.comb(x, y)) // outputs: (List(2, 6, 12),20)
最后的输出是“自然”的方式,但是 de 编译器怎么知道怎么做呢? 我一直在尝试在 Cats 的源代码中寻找它,但我在 Scala 方面的经验不如能够知道要寻找什么。我想同样的方法也适用于类似的结构,比如半群。
【问题讨论】:
-
我复制/粘贴了您的整个示例并收到此错误:
error: could not find implicit value for parameter m: Monoid[(List[Int], Int)]。在某处必须有这些类型的实例。 -
我认为您将自己的
Monoid与 cats 混在一起,对吗?无论如何,cats 为元组提供一个实例,就像它为任何List或任何Option提供一个实例一样,通过使用隐式推导并要求证明元组的类型也具有@987654327 @ 与它们关联的实例。 - 也许你的问题是这样的?如何编码复杂类型的typeclass派生? -
是的@LuisMiguelMejíaSuárez,我在询问这些事情是如何实现的,以便让编译器知道如果我只为这两种类型提供幺半群操作,当我调用 comb 函数时,它必须对每个单独执行组件。
-
@Dioni 您要查找的代码在此处生成:github.com/typelevel/cats/blob/…
标签: scala functional-programming scala-cats