【问题标题】:Scala typeclass derivation for collections集合的 Scala 类型类派生
【发布时间】:2016-03-17 05:46:51
【问题描述】:

我想编写一个类型类来静态编码我可以输出的所有内容到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]    
  }

现在我可以这样写了:

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

但是,现在我想为所有Iterables 写一个Write

   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()
      }
    }

但是,我还是编译失败:

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

理想情况下,我也应该能够派生嵌套的可迭代对象,例如:

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

我该怎么办?我查看了CanBuild,但这在构建集合时很有用;在这种情况下,我正在解构一个集合。

【问题讨论】:

  • 好吧,你的Write是不变的,这编译output(out, Set.empty[String].toIterable)
  • 噢!我以为我有它:)

标签: scala typeclass


【解决方案1】:

你可以像这样在 trait Write 中声明类型参数 A 是逆变的:

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

然后应该编译

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多