gpt4 book ai didi

具有泛型的Scala类型类

转载 作者:行者123 更新时间:2023-12-04 04:04:48 26 4
gpt4 key购买 nike

我一直在使用Scala中的typeclass模式,但是当我使用的类型是泛型时,我无法弄清楚如何实现隐式伴侣对象。

例如,假设我已经为类型类定义了一个特征,该特征提供了用于将内容放入Box es的函数。

case class Box[A](value: A)

trait Boxer[A] {
def box(instance: A): Box[A]
def unbox(box: Box[A]): A
}

implicit object IntBoxer extends Boxer[Int] {
def box(instance: Int) = Box(instance)
def unbox(box: Box[Int]) = box.value
}

def box[A : Boxer](value: A) = implicitly[Boxer[A]].box(value)
def unbox[A : Boxer](box: Box[A]) = implicitly[Boxer[A]].unbox(box)

这按预期工作,使我能够为各种类型提供 Boxer的实现。但是,我有 而不是的想法,当我希望作用的类型是泛型本身时,我将如何执行此操作。假设我希望能够在任何 Boxer上使用我的 Seq[A]。 Scala中的 object不能包含类型参数,因此我不知所措:
// Will not compile - object cannot have type arguments
implicit object SeqBoxer[A] extends Boxer[Seq[A]] { ... }

// Will not compile - 'A' is unrecognized
implicit object SeqBoxer extends Boxer[Seq[A]] { ... }

// Compiles but fails on execution, as this doesn't implement an implicit
// conversion for _specific_ instances of Seq
implicit object SeqBoxer extends Boxer[Seq[_]] {
def box(instance: Seq[_]) = Box(instance)
def unbox(box: Box[Seq[_]]) = box.value
}

// Will not compile - doesn't technically implement Boxer[Seq[_]]
implicit object SeqBoxer extends Boxer[Seq[_]] {
def box[A](instance: Seq[A]) = Box(instance)
def unbox[A](box: Box[Seq[A]]) = box.value
}

// Compiles, but won't resolve with 'implicitly[Boxer[Seq[Foo]]]'
// I had high hopes for this one, too :(
implicit def seqBoxer[A]() = new Boxer[Seq[A]] {
def box(instance: Seq[A]) = Box(instance)
def unbox(box: Box[Seq[A]]) = box.value
}

有什么方法可以支持泛型类型的隐式转换,而不必为每个内部类型隐式包含一个单独的对象?

最佳答案

实际上,您真的很亲密。您需要从seqBoxer[A]除去括号。否则,编译器将其视为() => Boxer[Seq[A]]的隐式转换,而不是简单的可用隐式Boxer[Seq[A]]。为了达到良好的效果,将隐式方法的返回类型设为显式也是一个好主意。

implicit def seqBoxer[A]: Boxer[Seq[A]] = new Boxer[Seq[A]] {
def box(instance: Seq[A]) = Box(instance)
def unbox(box: Box[Seq[A]]) = box.value
}

scala> box(Seq(1, 2, 3))
res16: Box[Seq[Int]] = Box(List(1, 2, 3))

实际上,您可以使用相同的方法为任何 Boxer[A]创建通用的 A,以使其行为相同。
implicit def boxer[A]: Boxer[A] = new Boxer[A] {
def box(instance: A): Box[A] = Box(instance)
def unbox(box: Box[A]): A = box.value
}

scala> box("abc")
res19: Box[String] = Box(abc)

scala> box(List(1, 2, 3))
res20: Box[List[Int]] = Box(List(1, 2, 3))

scala> unbox(res20)
res22: List[Int] = List(1, 2, 3)

scala> box(false)
res23: Box[Boolean] = Box(false)

关于具有泛型的Scala类型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29950352/

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