kri*_*ath 0 generics types scala
假设我将类型a定义为类型元组
type a = (Int, String, Int)
Run Code Online (Sandbox Code Playgroud)
我将泛型类定义Foo为
class Foo[A]{}
Run Code Online (Sandbox Code Playgroud)
是否有任何方法是 Scala(最好是原生 Scala)可以转换a为b泛型类型的元组?
type b = (Foo[Int], Foo[String], Foo[Int])
Run Code Online (Sandbox Code Playgroud)
尽管shapeless在 scala 2.* 中,对于没有typelevel 或宏的本机 scala来说这是不可能的,但可以创建一个函数,将类型 a 的值映射到类型 b 的值。您应该做的一件事是定义trait LiftFoo[T]
具有单一方法的typeclassdef lift[T](t: T)(implicit instance: LiftFoo[T]): Foo[T]并为您想要的所有类型实现。
然后你可以用 polyfunction 映射你的元组:
object Bla{
import shapeless.syntax.std.tuple._
import shapeless.syntax._
import shapeless.poly._
case class Foo[T](t: T)
trait LiftFoo[T] {
def liftImpl(t: T): Foo[T]
}
object LiftFoo {
def lift[T](t: T)(implicit instance: LiftFoo[T]): Foo[T] = instance.liftImpl(t)
}
implicit val liftInt: LiftFoo[Int] = {Foo(_)}
implicit val liftString: LiftFoo[String] = {Foo(_)}
implicit val liftDouble: LiftFoo[Double] = {Foo(_)}
val a: (Int, Int, String, Double) = ???
object LiftFooPoly extends Poly1 {
implicit def onLiftable[T: LiftFoo] = at[T](LiftFoo.lift[T])
}
val b = a.map{LiftFooPoly}
}
Run Code Online (Sandbox Code Playgroud)
但是,scala 3(即 Dotty)将允许在类型级别使用lambdas和match types执行此操作。Typelambda 允许type LiftFoo[T] = [T] =>> Foo[T]
scala 3 中的表单类型和匹配类型以及元组现在类似于 HList,您可以使用匹配类型递归遍历其元素:
type TupleLiftFoo[Xs <: Tuple] <: Tuple = Xs match
case Unit => Unit
case x *: xs => LiftFoo[x] *: TupleLiftFoo[xs]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |