Generic[A] 其中 A 是 Class?
Generic[A] where A is a Class?
使用 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]
^
shapeless 可以产生 Generic[F]
吗?如果是,怎么做?
您想要 F
的代表是什么?你可以说它应该是 HNil
,但是 x
在 class 的主体之外是不可见的,所以 Shapeless 决定根本不提供任何实例。这是 "just" 一个设计决定——在我看来是正确的,但很容易想象 Shapeless 为您的 class.
提供 HNil
实例
为 F
定义自己的实例也相当容易,这是可能的,因为 Generic
只是另一种类型 class:
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
}
}
作为另一个答案说明,您可以通过将 class 更改为案例 class 让 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@73e5dfa9
scala> class F()
defined class F
scala> shapeless.Generic[F]
res1: shapeless.Generic[F]{type Repr = shapeless.HNil} = anon$macro@4e0e355c
您不能将参数设为 var
或将 class 设为抽象(除非它是密封的并且具有大小写 class 或对象实现)。或者更确切地说,您可以,但是您必须再次定义自己的实例,并且您将违反 Generic
文档中的约定,该文档规定特征化类型应该是 "immutable data type that has a canonical way of constructing and deconstructing instances"。
据我所知,class 定义的排列方式的确切细节将得到 Generic
个实例,但在任何地方都没有记录(并且 the source 不容易阅读),但通过在 REPL 中尝试特定案例,可以很容易地测试您感兴趣的限制。
使用 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]
^
shapeless 可以产生 Generic[F]
吗?如果是,怎么做?
您想要 F
的代表是什么?你可以说它应该是 HNil
,但是 x
在 class 的主体之外是不可见的,所以 Shapeless 决定根本不提供任何实例。这是 "just" 一个设计决定——在我看来是正确的,但很容易想象 Shapeless 为您的 class.
HNil
实例
为 F
定义自己的实例也相当容易,这是可能的,因为 Generic
只是另一种类型 class:
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
}
}
作为另一个答案说明,您可以通过将 class 更改为案例 class 让 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@73e5dfa9
scala> class F()
defined class F
scala> shapeless.Generic[F]
res1: shapeless.Generic[F]{type Repr = shapeless.HNil} = anon$macro@4e0e355c
您不能将参数设为 var
或将 class 设为抽象(除非它是密封的并且具有大小写 class 或对象实现)。或者更确切地说,您可以,但是您必须再次定义自己的实例,并且您将违反 Generic
文档中的约定,该文档规定特征化类型应该是 "immutable data type that has a canonical way of constructing and deconstructing instances"。
据我所知,class 定义的排列方式的确切细节将得到 Generic
个实例,但在任何地方都没有记录(并且 the source 不容易阅读),但通过在 REPL 中尝试特定案例,可以很容易地测试您感兴趣的限制。