Mic*_*tte 6 scala higher-kinded-types type-constructor recursive-type
我有一种情况,我需要一个可以采用类型的方法:
Array[Int]
Array[Array[Int]]
Array[Array[Array[Int]]]
Array[Array[Array[Array[Int]]]]
etc...
Run Code Online (Sandbox Code Playgroud)
让我们称这种类型的RAI为"递归的整数数组"
def make(rai: RAI): ArrayPrinter = { ArrayPrinter(rai) }
Run Code Online (Sandbox Code Playgroud)
其中ArrayPrinter是一个用RAI初始化并迭代整个rai的类(假设它打印了这个数组中的所有值[Array [Int]])
val arrayOfArray: Array[Array[Int]] = Array(Array(1, 2), Array(3, 4))
val printer: ArrayPrinter[Array[Array[Int]]] = make(arrayOfArray)
printer.print_! // prints "1, 2, 3, 4"
Run Code Online (Sandbox Code Playgroud)
它还可以返回原始Array [Array [Int]]而不会丢失任何类型信息.
val arr: Array[Array[Int]] = printer.getNestedArray()
Run Code Online (Sandbox Code Playgroud)
你如何在Scala中实现这一点?
我们首先关注类型。根据您的定义,类型T应该作为参数进行类型检查,以确定ArrayPrinter它是否被以下类型函数接受:
def accept[T]: Boolean =
T match { // That's everyday business in agda
case Array[Int] => true
case Array[X] => accept[X]
case _ => false
}
Run Code Online (Sandbox Code Playgroud)
在 Scala 中,您可以使用隐式解析对该类型函数进行编码:
trait RAI[T]
object RAI {
implicit val e0: RAI[Array[Int]] = null
implicit def e1[T](implicit i: RAI[T]): RAI[Array[T]] = null
}
case class ArrayPrinter[T: RAI](getNestedArray: T) // Only compiles it T is a RAI
Run Code Online (Sandbox Code Playgroud)
要打印内容,最简单的解决方案是将rai: T视为rai: Any:
def print_!: Unit = {
def print0(a: Any): Unit = a match {
case a: Int => println(a)
case a: Array[_] => a.foreach(print0)
case _ => ???
}
}
Run Code Online (Sandbox Code Playgroud)
您也可以print_!使用类型类来编写,但这可能会比上面的方法效率更低并且需要更多的时间......留给读者作为练习;-)