【问题标题】:In Shapeless, can I supply an instance of `LabelledGeneric` for non case classes that will enable automatic derivation of typeclass instances?在 Shapeless 中,我可以为非案例类提供一个“LabelledGeneric”的实例,以启用类型类实例的自动派生吗?
【发布时间】:2015-01-24 08:25:25
【问题描述】:

我有一个 json 库,它通过遵循 Scala 中的类型类模式定义了一个 ReadCodec 的概念(它定义了如何读取 json)。此库使用 Shapeless' Typeclass 构造来为任何案例类免费派生 ReadCodec 的自动实例。

现在,我有一个代码生成器,它在 Scala 中生成不是案例类的类(但可能应该是)。我可以让代码生成器为我们现在拥有的每个类生成 ReadCodec 的实例。但是现在如果我希望生成的类支持某种新形式的序列化,我需要修改代码生成以输出这个新类型类的实例。

有没有办法我可以修改代码生成器以输出带有 LabelledGeneric 实例的类或其他可以利用为案例类生成(通过宏)自动实例的机制的方法?这样,生成的代码可以与任何使用 Shapeless'Typeclass 实现实例化的类型类模式互操作。

【问题讨论】:

  • 当然,只需生成LabelledGeneric 实例。有什么困难/问题?
  • @Imm 哈哈,有趣的是,我只是假设它不可能那么简单......仍然希望遇到问题,但我想我只需要尝试找出答案。谢谢你让我相信这可能真的有效。
  • @lmm 这是一个合理的问题——定义LabelledGeneric 实例并非易事(由于您需要引用单例类型等)。

标签: scala code-generation typeclass shapeless


【解决方案1】:

有一个棘手的步骤,但您绝对可以定义自己的 LabelledGeneric 实例。这里为了举例,我将使用 Alex Archambault 的 argonaut-shapeless 库,它实际上并没有使用 TypeClass,但它确实使用了 LabelledGeneric,原理是一样的。

我们班的第一名:

class Foo(val i: Int, val s: String)

那么对于我们的例子:

import shapeless._, labelled._, record._, syntax.singleton._

implicit object fooGeneric extends LabelledGeneric[Foo] {
  val iw = Witness('i)
  val sw = Witness('s)

  type Repr = FieldType[iw.T, Int] :: FieldType[sw.T, String] :: HNil

  def from(r: Repr): Foo = new Foo(r('i), r('s))
  def to(t: Foo): Repr = ('i ->> t.i) :: ('s ->> t.s) :: HNil
}

请注意,我们需要一种方法来引用 Repr 中记录键的单例类型,因此我们首先定义了几个见证人。这是棘手的部分。

现在你只要写这个:

import argonaut._, Argonaut._, Shapeless._

然后:

scala> implicitly[EncodeJson[Foo]].encode(new Foo(42, "foo"))
res0: argonaut.Json = {"s":"foo","i":42}

如果您愿意,我可以整理一个 LabelledTypeClass 示例,但想法完全相同。

【讨论】:

  • 请注意 Witness 实例现在是可有可无的,因为 Witness 现在有一个类型选择器:type Repr = FieldType[Witness.`'i`.T, Int] :: FieldType[Witness.`'s`.T, String] :: HNil
  • @al3xar 是的,我想我应该提到那个语法。对我来说还是有点太神奇了。
  • 这太棒了,谢谢!我刚刚找到时间尝试一下,经过一番修改后它成功了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-17
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 2020-04-08
  • 2015-11-12
  • 2021-11-19
相关资源
最近更新 更多