简体   繁体   中英

Is it possible to have a variable type list in Scala?

Is there a way of having a unknown number of types for a generic method? I'm currently experimenting with the Scala Type System and could not find any solution to this.

Classic varargs for parameters look like this:

def printAll(strings: String*) {
    strings.foreach(println)
}

But my question is, if there is something like that:

def magic[TYPES*](...) {
    for(t <- TYPES){
        typeOf[t] ...
    }
}

edit: The idea was, to implement a way to create Lists in square brackets like this:

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)

I'm afraid you can't have [TYPES*] in Scala.

If having [L <: HList] ( HList is heterogeneous list) is enough for you then with Shapeless you can do

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

Actually magic can be defined even simpler

import shapeless.ops.hlist.Reify
def magic[L <: HList](implicit reify: Reify.Aux[L, L]): L = reify()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM