是否可以在 Scala 中使用变量类型列表?
Is it possible to have a variable type list in Scala?
有没有办法让泛型方法拥有未知数量的类型?我目前正在试验 Scala 类型系统,找不到任何解决方案。
参数的经典可变参数如下所示:
def printAll(strings: String*) {
strings.foreach(println)
}
但我的问题是,如果有这样的事情:
def magic[TYPES*](...) {
for(t <- TYPES){
typeOf[t] ...
}
}
编辑:
这个想法是,实现一种在方括号中创建列表的方法,如下所示:
def magicList[A: TypeTag, B: TypeTag, C: TypeTag, D: TypeTag]: List[Any] = {
val a = typeOf[A] match { case ConstantType(a) => a.value }
val b = typeOf[B] match { case ConstantType(b) => b.value }
val c = typeOf[C] match { case ConstantType(c) => c.value }
val d = typeOf[D] match { case ConstantType(d) => d.value }
List(a,b,c,d)
}
magicList[1,2,3,4] == List(1,2,3,4)
恐怕你不能在 Scala 中使用 [TYPES*]
。
如果 [L <: HList]
(HList
是异构列表)对您来说足够了,那么您可以使用 Shapeless
import shapeless.{::, HList, HNil, Poly0, Poly1, Witness}
import shapeless.ops.hlist.{FillWith, Mapper}
object witnessPoly extends Poly1 {
// implicit def cse[A](implicit witness: Witness.Aux[A]): Case.Aux[A, A] = at(_ => witness.value)
implicit def cse[A <: Singleton](implicit valueOf: ValueOf[A]): Case.Aux[A, A] = at(_ => valueOf.value) // scala 2.13
}
object nullPoly extends Poly0 {
implicit def default[A]: ProductCase.Aux[HNil, A] = at(null.asInstanceOf[A])
}
def magic[L <: HList](implicit
mapper: Mapper.Aux[witnessPoly.type, L, L],
fillWith: FillWith[nullPoly.type, L]
): L = mapper(fillWith())
magic[Witness.`1`.T :: Witness.`"a"`.T :: Witness.`true`.T :: HNil] // 1 :: a :: true :: HNil
magic[1 :: "a" :: true :: HNil] // scala 2.13 // 1 :: a :: true :: HNil
magic[1 :: 2 :: 3 :: 4 :: HNil] // scala 2.13 // 1 :: 2 :: 3 :: 4 :: HNil
其实magic
可以定义得更简单
import shapeless.ops.hlist.Reify
def magic[L <: HList](implicit reify: Reify.Aux[L, L]): L = reify()
有没有办法让泛型方法拥有未知数量的类型?我目前正在试验 Scala 类型系统,找不到任何解决方案。
参数的经典可变参数如下所示:
def printAll(strings: String*) {
strings.foreach(println)
}
但我的问题是,如果有这样的事情:
def magic[TYPES*](...) {
for(t <- TYPES){
typeOf[t] ...
}
}
编辑: 这个想法是,实现一种在方括号中创建列表的方法,如下所示:
def magicList[A: TypeTag, B: TypeTag, C: TypeTag, D: TypeTag]: List[Any] = {
val a = typeOf[A] match { case ConstantType(a) => a.value }
val b = typeOf[B] match { case ConstantType(b) => b.value }
val c = typeOf[C] match { case ConstantType(c) => c.value }
val d = typeOf[D] match { case ConstantType(d) => d.value }
List(a,b,c,d)
}
magicList[1,2,3,4] == List(1,2,3,4)
恐怕你不能在 Scala 中使用 [TYPES*]
。
如果 [L <: HList]
(HList
是异构列表)对您来说足够了,那么您可以使用 Shapeless
import shapeless.{::, HList, HNil, Poly0, Poly1, Witness}
import shapeless.ops.hlist.{FillWith, Mapper}
object witnessPoly extends Poly1 {
// implicit def cse[A](implicit witness: Witness.Aux[A]): Case.Aux[A, A] = at(_ => witness.value)
implicit def cse[A <: Singleton](implicit valueOf: ValueOf[A]): Case.Aux[A, A] = at(_ => valueOf.value) // scala 2.13
}
object nullPoly extends Poly0 {
implicit def default[A]: ProductCase.Aux[HNil, A] = at(null.asInstanceOf[A])
}
def magic[L <: HList](implicit
mapper: Mapper.Aux[witnessPoly.type, L, L],
fillWith: FillWith[nullPoly.type, L]
): L = mapper(fillWith())
magic[Witness.`1`.T :: Witness.`"a"`.T :: Witness.`true`.T :: HNil] // 1 :: a :: true :: HNil
magic[1 :: "a" :: true :: HNil] // scala 2.13 // 1 :: a :: true :: HNil
magic[1 :: 2 :: 3 :: 4 :: HNil] // scala 2.13 // 1 :: 2 :: 3 :: 4 :: HNil
其实magic
可以定义得更简单
import shapeless.ops.hlist.Reify
def magic[L <: HList](implicit reify: Reify.Aux[L, L]): L = reify()