隐式方法的排序和无形的映射

时间:2017-02-02 04:00:25

标签: scala shapeless

使用无形时,隐式的排序似乎很重要。 请查看下面的示例代码,它不起作用。

import shapeless._

case class Userz(i: Int, j: String, k: Option[Boolean])

object r {
  def func(): Userz = {
    val a = Userz(100, "UserA", Some(false))
    val b = Userz(400, "UserB", None)

    val genA = Generic[Userz].to(a)
    val genB = Generic[Userz].to(b)

    val genC = genA zip genB

    val genD = genC.map(Mergerz)
    val User = Generic[Userz].from(genD)
    return User
  }
}
object Mergerz extends Poly1 {
  implicit def caseInt = at[(Int, Int)] {a => a._1 + a._2}
  implicit def caseString = at[(String, String)] {a => a._1 + a._2}
  implicit def caseBoolean = at[(Option[Boolean], Option[Boolean])] {a => Some(a._1.getOrElse(a._2.getOrElse(false)))}
}

r.func()

下面的代码将起作用

import shapeless._

case class Userz(i: Int, j: String, k: Option[Boolean])

object Mergerz extends Poly1 {
  implicit def caseInt = at[(Int, Int)] {a => a._1 + a._2}
  implicit def caseString = at[(String, String)] {a => a._1 + a._2}
  implicit def caseBoolean = at[(Option[Boolean], Option[Boolean])] {a => Some(a._1.getOrElse(a._2.getOrElse(false)))}
}

object r {
  def func(): Userz = {
    val a = Userz(100, "UserA", Some(false))
    val b = Userz(400, "UserB", None)

    val genA = Generic[Userz].to(a)
    val genB = Generic[Userz].to(b)

    val genC = genA zip genB

    val genD = genC.map(Mergerz)
    val User = Generic[Userz].from(genD)
    return User
  }
}


r.func()

我的问题是,为什么订单很重要?我已经尝试导入无效的implicits。

1 个答案:

答案 0 :(得分:1)

因为文件中的类型推断基本上是从上到下的。当它进行类型检查func时,它还没有得到caseInt等,并且不知道它们是合适的。注释它们的类型应该也可以使用,并且通常建议用于implicits,但是在使用像Shapeless这样的库时可能会有问题:请参阅Shapeless not finding implicits in test, but can in REPL作为示例。