Scala shapeless selection from HList of dependent types 问题
Scala shapeless selection from HList of dependent types problem
我有一个依赖于类型的 Cf 类型,它存储单调字符串:
trait Cf {
type Name <: String with Singleton
def value: Name
}
object Cf {
type Aux[A <: String with Singleton] = Cf { type Name = A }
def apply(name: String): Aux[name.type] = {
val w = name.witness
new Cf {
override type Name = w.T
override def value: Name = w.value
}
}
}
成像有另一个 class Dbtest,它只存储某些 HList 类型的列:
class Dbtest[T <: HList](val columns: T)
然后我想为我的 Cf 类型编写一些扩展方法,但是有一个限制:要调用扩展方法的实例的类型必须显示在 Dbtest 实例的 HList 中:
object Ops {
implicit class CfOps[C, N <: String with Singleton, T <: HList](ecf: C)
(
implicit
db: Dbtest[T]
, ev: C =:= Cf.Aux[N]
, selector: Selector[T, C]
) {
private val cf = selector(db.columns)
def simplePrint(): Unit = println(cf.value)
}
}
正在创建 Cf 实例和 Dbtest 实例,其中一些包含在其中:
object Test extends App {
val c = Cf("c")
val b = Cf("b")
val g = Cf("g")
implicit val db = new Dbtest(c :: b :: HNil)
...
我希望编译它,因为在 HList 中指定了 c
:
c.simplePrint()
这不会编译,因为 g
没有出现在 HList 中:
g.simplePrint()
主要问题是 - 我无法正确指定隐式选择器类型,因此编译器看不到我的 simplePrint()
方法:
value simplePrint is not a member of Cf{type Name = String("c")}
有什么方法可以正确指定选择器类型吗?
没有办法在CfOps(ecf)
中推断N
具体ecf: C
,所以N
只是一些抽象类型,没有隐含的证据C =:= Cf.Aux[N]
.
尝试将 CfOps
的定义替换为
implicit class CfOps[N <: String with Singleton, T <: HList](ecf: Cf.Aux[N])(
implicit
db: Dbtest[T],
selector: Selector[T, Cf.Aux[N]]
) {
private val cf = selector(db.columns)
def simplePrint(): Unit = println(cf.value)
}
然后
import Ops._
c.simplePrint() // compiles
//g.simplePrint() // doesn't compile
我有一个依赖于类型的 Cf 类型,它存储单调字符串:
trait Cf {
type Name <: String with Singleton
def value: Name
}
object Cf {
type Aux[A <: String with Singleton] = Cf { type Name = A }
def apply(name: String): Aux[name.type] = {
val w = name.witness
new Cf {
override type Name = w.T
override def value: Name = w.value
}
}
}
成像有另一个 class Dbtest,它只存储某些 HList 类型的列:
class Dbtest[T <: HList](val columns: T)
然后我想为我的 Cf 类型编写一些扩展方法,但是有一个限制:要调用扩展方法的实例的类型必须显示在 Dbtest 实例的 HList 中:
object Ops {
implicit class CfOps[C, N <: String with Singleton, T <: HList](ecf: C)
(
implicit
db: Dbtest[T]
, ev: C =:= Cf.Aux[N]
, selector: Selector[T, C]
) {
private val cf = selector(db.columns)
def simplePrint(): Unit = println(cf.value)
}
}
正在创建 Cf 实例和 Dbtest 实例,其中一些包含在其中:
object Test extends App {
val c = Cf("c")
val b = Cf("b")
val g = Cf("g")
implicit val db = new Dbtest(c :: b :: HNil)
...
我希望编译它,因为在 HList 中指定了 c
:
c.simplePrint()
这不会编译,因为 g
没有出现在 HList 中:
g.simplePrint()
主要问题是 - 我无法正确指定隐式选择器类型,因此编译器看不到我的 simplePrint()
方法:
value simplePrint is not a member of Cf{type Name = String("c")}
有什么方法可以正确指定选择器类型吗?
没有办法在CfOps(ecf)
中推断N
具体ecf: C
,所以N
只是一些抽象类型,没有隐含的证据C =:= Cf.Aux[N]
.
尝试将 CfOps
的定义替换为
implicit class CfOps[N <: String with Singleton, T <: HList](ecf: Cf.Aux[N])(
implicit
db: Dbtest[T],
selector: Selector[T, Cf.Aux[N]]
) {
private val cf = selector(db.columns)
def simplePrint(): Unit = println(cf.value)
}
然后
import Ops._
c.simplePrint() // compiles
//g.simplePrint() // doesn't compile