gpt4 book ai didi

scala - 在没有隐式证据对象的情况下直接使用 Scala 类型类

转载 作者:行者123 更新时间:2023-12-02 17:27:03 26 4
gpt4 key购买 nike

我想直接使用类型类的函数,而不必引用隐式证据对象。

现在我已经按照推荐的方式实现了一个类型类(至少我是这么认为的):

object Main {
import Implicits._
import Implicits.monoidInt._

def main(args: Array[String]): Unit = {
println(addTwice(1,2))
}
}

object Implicits {
implicit object monoidInt extends Monoid[Int] {
def zero: Int = 0
def append(x: Int, y: Int): Int = x + y
}
}

trait Monoid[A] {
def zero: A
def append(x: A, y: A): A
}

而不是像这样编写 addTwice:

def addTwice[A](x: A, y: A)(implicit ev: Monoid[A]): A = {
ev.append(ev.append(x,y), y)
}

我想写:

def addTwice[A: Monoid[A]](x: A, y: A): A = x.append(y).append(y)

这可能吗?

最佳答案

是的,这是可能的。您需要所谓的 Ops。它允许向定义了类型类实例的类的对象添加方法。

您定义具有该值和类型类实例的 MonoidOps 特征,然后在其方法中使用它们,因此基本上它封装了 ev 变量的用法。

然后定义从 AMonoidOps[A] 的转换,设置对象以及通过隐式参数获取的实例。

trait Monoid[A] {
def zero: A
def append(x: A, y: A): A
}

object Implicits {
implicit object monoidInt extends Monoid[Int] {
def zero: Int = 0
def append(x: Int, y: Int): Int = x + y
}

trait MonoidOps[A] {
def instance: Monoid[A]
def self: A
def |+|(y: A): A = instance.append(self, y)
}

implicit def toMonoidOps[A](target: A)(implicit M: Monoid[A]) = new MonoidOps[A] {
val instance = M
val self = target
}
}

import Implicits._

def addTwice[A: Monoid](x: A, y: A): A = x |+| y |+| y

scala> println(addTwice(1,2))
5

MonoidOpstoMonoidOps 可以用这样的隐式类替换:

implicit class MonoidOps[A](val self: A)(implicit M: Monoid[A]) {
def |+|(y: A): A = M.append(self, y)
}

看看simulacrum可以为您生成样板的项目。

关于scala - 在没有隐式证据对象的情况下直接使用 Scala 类型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37922492/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com