简体   繁体   中英

Scala typeclass derivation for collections

I wanted to write a typeclass to staticly encode what all I can output to a Printer :

  import java.io.PrintWriter

  trait Write[A] {
    def apply(out: PrintWriter)(x: A): Unit
  }
  object Write {
    def apply[A] = new Write[A] {
      def apply(out: PrintWriter)(x: A) = out.print(x)
    }
    implicit val string     : Write[String]     = Write[String]
    implicit val char       : Write[Char]       = Write[Char]
    implicit val boolean    : Write[Boolean]    = Write[Boolean]
    implicit val int        : Write[Int]        = Write[Int]
    implicit val long       : Write[Long]       = Write[Long]
    implicit val bigInt     : Write[BigInt]     = Write[BigInt]
    implicit val double     : Write[Double]     = Write[Double]
    implicit val bigDecimal : Write[BigDecimal] = Write[BigDecimal]    
  }

Now I can write this:

def output[A(out: PrintWriter, x: A)(implicit write: Write[A]) = write(out)(x)

output(out, "hello") // compiles
output(out, 1) //compiles
output(out, Set.empty[String]) // does not compile

But, now I want to write a Write for all Iterable s:

   implicit def iterable[A](implicit write: Write[A]) = new Write[Iterable[A]] {
      def apply(out: PrintWriter)(xs: Iterable[A]) = {
        xs.foreach(write(out))
        out.println()
      }
    }

But, I still fail to compile this:

output(out, Set.empty[String]) // should compile!!

Ideally, I should be able to derive nested iterables too eg:

output(out, Array.ofDim[Int](100, 100)) // should compile!!

What shall I do? I looked at CanBuild but that is useful when constructing a collection; in this case I am deconstructing a collection.

You can declare the type parameter A in trait Write to be contravariant like so:

trait Write[-A] {
  def apply(out: PrintWriter)(x: A): Unit
}

and this should then compile

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