gpt4 book ai didi

scala - 在 Scala 中定义要由 case 类扩展的特征

转载 作者:行者123 更新时间:2023-12-04 10:16:01 25 4
gpt4 key购买 nike

我有一些案例类有一个方法 tupled在其伴生对象中定义。从下面伴随对象中的代码可以看出,这只是代码重复。

case class Book(id: Int, isbn: String, name: String)

object Book {
def tupled = (Book.apply _).tupled // Duplication
}


case class Author(id: Int, name: String)

object Author {
def tupled = (Author.apply _).tupled // Duplication
}

从另一个问题( can a scala self type enforce a case class type )看来,我们似乎无法将 trait 的 self 类型强制为 case 类。

有没有办法定义可以应用如下的特征(比如 Tupled )?
// What would be value of ???
trait Tupled {
self: ??? =>

def tupled = (self.apply _).tupled
}

// Such that I can replace tupled definition with Trait
object Book extends Tupled {
}

最佳答案

因为FunctionN之间没有关系Scala 中的类型,如果没有 arity 级别的样板,就不可能在某处做到这一点——只是没有办法对伴随对象的 apply 进行抽象。方法而不枚举所有可能的成员数量。

您可以使用一堆 CompanionN[A, B, C, ...] 手动完成此操作。特质,但这很烦人。 Shapeless提供了一个更好的解决方案,它允许您编写如下内容:

import shapeless.{ Generic, HList }, shapeless.ops.product.ToHList

class CaseClassCompanion[C] {
def tupled[P <: Product, R <: HList](p: P)(implicit
gen: Generic.Aux[C, R],
toR: ToHList.Aux[P, R]
): C = gen.from(toR(p))
}

进而:
case class Book(id: Int, isbn: String, name: String)
object Book extends CaseClassCompanion[Book]

case class Author(id: Int, name: String)
object Author extends CaseClassCompanion[Author]

你可以这样使用:
scala> Book.tupled((0, "some ISBN", "some name"))
res0: Book = Book(0,some ISBN,some name)

scala> Author.tupled((0, "some name"))
res1: Author = Author(0,some name)

您甚至可能不想要 CaseClassCompanion部分,因为可以构造一个将元组转换为 case 类的通用方法(假设成员类型对齐):
class PartiallyAppliedProductToCc[C] {
def apply[P <: Product, R <: HList](p: P)(implicit
gen: Generic.Aux[C, R],
toR: ToHList.Aux[P, R]
): C = gen.from(toR(p))
}

def productToCc[C]: PartiallyAppliedProductToCc[C] =
new PartiallyAppliedProductToCc[C]

进而:
scala> productToCc[Book]((0, "some ISBN", "some name"))
res2: Book = Book(0,some ISBN,some name)

scala> productToCc[Author]((0, "some name"))
res3: Author = Author(0,some name)

这将适用于具有多达 22 个成员的案例类(因为如果参数超过 22 个,则伴随对象上的 apply 方法不能被 eta-expanded 为函数)。

关于scala - 在 Scala 中定义要由 case 类扩展的特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34880692/

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