Scala Recursive implementation of type and type

I have a situation where I need a method that can take types:

Array[Int]
Array[Array[Int]]
Array[Array[Array[Int]]]
Array[Array[Array[Array[Int]]]]
etc...

let this type of RAI for "recursive int array"

def make(rai: RAI): ArrayPrinter = { ArrayPrinter(rai) }

Where ArrayPrinter is a class that is initialized by RAI and iterates over the entire rai (let it print all the values ​​in this array [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" 

It can also return the original [Array [Int]] array without losing type information.

val arr: Array[Array[Int]] = printer.getNestedArray() 

How do you implement this in Scala?

+6
source share
2 answers

Focus on the type first. According to your definition, the type Tshould look like an argument for ArrayPrinter, it is accepted by the following type function:

def accept[T]: Boolean =
  T match { // That everyday business in agda
    case Array[Int] => true
    case Array[X]   => accept[X]
    case _          => false
  }

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

, 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 _           => ???
  }
}

print_! , , , , ... : -)

+3

, , , . , ( ) . Ordering. , , , . .

:

abstract class ArrayPrinter[A] {
  def mkString(a: A): String
}
implicit object BaseArrayPrinter extends ArrayPrinter[Int] {
  override def mkString(x: Int) = x.toString
}
class WrappedArrayPrinter[A](wrapped: ArrayPrinter[A]) extends ArrayPrinter[Array[A]] {
  override def mkString(xs: Array[A]) = xs.map(wrapped.mkString).mkString(", ")
}
implicit def makeWrappedAP[A](implicit wrapped: ArrayPrinter[A]): ArrayPrinter[Array[A]] = new WrappedArrayPrinter(wrapped)

def printHello[A](xs: A)(implicit printer: ArrayPrinter[A]): Unit = {
  println("hello, array: " + printer.mkString(xs))
}

, , , RAIOps ( ArrayPrinter) . "" "", , ..

, . - , ArrayPrinter Set[Int], . Ordering.

0

All Articles