使用隐式类型证据来满足类型约束
Using implicit type evidence to satisfy type constraint
我正在尝试制作一个具有多种不受约束类型的构建器,该构建器可以构建具有受约束类型的 class。如何使用类型边界的隐式证据来满足类型约束?
例如我想构建一个 class:
class NameClass[N <: String](name: N)
我使用的生成器如下所示:
class NameClassBuilder[N](n: N) {
def name[NewN <: String](name: NewN) = new NameClassBuilder[NewN](name)
def build(implicit ev: N <:< String) : NameClass[N] = new NameClass[N](n)
}
object NameClassBuilder {
def builder : NameClassBuilder[Unit] = new NameClassBuilder[Unit]()
}
想法是您可以从虚拟 type/value 开始,然后在添加字段时更新类型。通过使用类型正确的证据,您只能在类型有意义时构建它。
问题是编译不通过,因为NameClassBuilder
中的N
不满足NameClass
中的类型约束N <: String
,即使我已经包含了它确实如此的证据。
error: type arguments [N] do not conform to class NameClass's type parameter bounds [N <: String]
def build(implicit ev: N <:< String) : NameClass[N] = new NameClass[N](n)
有什么方法可以利用证据来满足这个约束吗?
您是在告诉编译器,当函数 build
被调用时,应该存在符合 N <:< String
的隐含证据。但在NameClassBuilder
范围内,N
符合Any
.
你可以试试:
class NameClassBuilder[N](n: N) {
def name[NewN <: String](name: NewN) = new NameClassBuilder[NewN](name)
def build[U <: String](implicit ev: N <:< String): NameClass[U] = new NameClass[U](n.asInstanceOf)
}
您可以 return NameClass[N with String]
代替。 N with String <: String
对于任何 N
,如果实际上 N <: String
那么 N with String = N
。您在 build
中的 N <:< String
需要将 n: N
转换为 N with String
。
def build(implicit ev: N <:< String): NameClass[N with String] = {
type F[+X] = N with X
new NameClass(ev.liftCo[F](n))
}
我正在尝试制作一个具有多种不受约束类型的构建器,该构建器可以构建具有受约束类型的 class。如何使用类型边界的隐式证据来满足类型约束?
例如我想构建一个 class:
class NameClass[N <: String](name: N)
我使用的生成器如下所示:
class NameClassBuilder[N](n: N) {
def name[NewN <: String](name: NewN) = new NameClassBuilder[NewN](name)
def build(implicit ev: N <:< String) : NameClass[N] = new NameClass[N](n)
}
object NameClassBuilder {
def builder : NameClassBuilder[Unit] = new NameClassBuilder[Unit]()
}
想法是您可以从虚拟 type/value 开始,然后在添加字段时更新类型。通过使用类型正确的证据,您只能在类型有意义时构建它。
问题是编译不通过,因为NameClassBuilder
中的N
不满足NameClass
中的类型约束N <: String
,即使我已经包含了它确实如此的证据。
error: type arguments [N] do not conform to class NameClass's type parameter bounds [N <: String]
def build(implicit ev: N <:< String) : NameClass[N] = new NameClass[N](n)
有什么方法可以利用证据来满足这个约束吗?
您是在告诉编译器,当函数 build
被调用时,应该存在符合 N <:< String
的隐含证据。但在NameClassBuilder
范围内,N
符合Any
.
你可以试试:
class NameClassBuilder[N](n: N) {
def name[NewN <: String](name: NewN) = new NameClassBuilder[NewN](name)
def build[U <: String](implicit ev: N <:< String): NameClass[U] = new NameClass[U](n.asInstanceOf)
}
您可以 return NameClass[N with String]
代替。 N with String <: String
对于任何 N
,如果实际上 N <: String
那么 N with String = N
。您在 build
中的 N <:< String
需要将 n: N
转换为 N with String
。
def build(implicit ev: N <:< String): NameClass[N with String] = {
type F[+X] = N with X
new NameClass(ev.liftCo[F](n))
}