使用Shapeless,我尝试通过以下方式获取Generic[F]
:
import shapeless._
class F(x: Int)
但失败了:
scala> Generic[F]
<console>:20: error: could not find implicit value for parameter gen: shapeless.Generic[F]
Generic[F]
^
变形可以产生
Generic[F]
吗?如果是这样,怎么办? 最佳答案
您想要F
的什么表示形式?您可以说它应该是HNil
,但是x
在类主体之外不可见,因此Shapeless决定完全不提供任何实例。这“只是”一项设计决定,在我看来是正确的决定,但是很容易想象Shapeless为您的类提供了HNil
实例。
为F
定义自己的实例也相当容易,这是可能的,因为Generic
只是另一个类型类:
import shapeless._
class F(x: Int)
object F {
implicit val genericF: Generic.Aux[F, HNil] = new Generic[F] {
type Repr = HNil
def from(r: HNil): F = new F(0)
def to(t: F): HNil = HNil
}
}
另一个答案是,通过将类更改为案例类,可以使Shapeless为您提供实例。但是,这并不是唯一的方法-您还可以将构造函数参数更改为
val
或将其删除:scala> class F(val x: Int)
defined class F
scala> shapeless.Generic[F]
res0: shapeless.Generic[F]{type Repr = shapeless.::[Int,shapeless.HNil]} = anon$macro$3$1@73e5dfa9
scala> class F()
defined class F
scala> shapeless.Generic[F]
res1: shapeless.Generic[F]{type Repr = shapeless.HNil} = anon$macro$5$1@4e0e355c
但是,您不能将参数设为
var
或将类抽象化(除非已将其密封并具有case类或对象实现)。或许可以,但是然后您必须再次定义自己的实例,并且要破坏Generic
文档中的约定,该文档指出特征类型应该是“具有规范方法的不可变数据类型”。构造和解构实例”。据我所知,没有任何地方会记录
Generic
实例将获得哪种类定义的确切安排的详细信息(而且the source并不容易阅读),但是通过尝试测试您感兴趣的限制非常容易列出REPL中的特定案例。关于scala - 泛型[A]其中A是类?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41477065/