die folgenden von Travis Brown Bildungs- und gut geschrieben Da Type classes and generic derivation:Abweichende Implicits für Case-Klasse w/Gehäuse Klasse Argument
case class Person(name: String, age: Double)
trait Parser[A] {
def apply(s: String): Option[A]
}
implicit val hnilParser: Parser[HNil] = new Parser[HNil] {
def apply(s: String): Option[HNil] = if(s.isEmpty) Some(HNil) else None
}
implicit def hconsParser[H: Parser, T <: HList: Parser]: Parser[H :: T] = new Parser[H :: T] {
def apply(s: String): Option[H :: T] = s.split(",").toList match {
case cell +: rest => for {
head <- implicitly[Parser[H]].apply(cell)
tail <- implicitly[Parser[T]].apply(rest.mkString(","))
} yield head :: tail
}
}
implicit val stringParser: Parser[String] = new Parser[String] {
def apply(s: String): Option[String] = Some(s)
}
implicit val intParser: Parser[Int] = new Parser[Int] {
def apply(s: String): Option[Int] = Try(s.toInt).toOption
}
implicit val doubleParser: Parser[Double] = new Parser[Double] {
def apply(s: String): Option[Double] = Try(s.toDouble).toOption
}
implicit val booleanParser: Parser[Boolean] = new Parser[Boolean] {
def apply(s: String): Option[Boolean] = Try(s.toBoolean).toOption
}
implicit def caseClassParser[A, R <: HList](implicit gen: Generic[A] { type Repr = R },
reprParser: Parser[R]): Parser[A] =
new Parser[A] {
def apply(s: String): Option[A] = reprParser.apply(s).map(gen.from)
}
object Parser {
def apply[A](s: String)(implicit parser: Parser[A]): Option[A] = parser(s)
}
implicit val stringParser: Parser[String] = new Parser[String] {
def apply(s: String): Option[String] = Some(s)
}
implicit val intParser: Parser[Int] = new Parser[Int] {
def apply(s: String): Option[Int] = Try(s.toInt).toOption
}
implicit val doubleParser: Parser[Double] = new Parser[Double] {
def apply(s: String): Option[Double] = Try(s.toDouble).toOption
}
Ich war neugierig, zu versuchen, ein Parser[X]
zu bekommen, wo X
ein Fall-Klasse mit a Person
Argument, dh einen Fall Klasse:
case class PersonWrapper(person: Person, x: Int)
Dennoch bekomme ich einen Fehler:
scala> Parser[PersonWrapper]("kevin,66,42")
<console>:15: error: diverging implicit expansion for type net.Test.Parser[net.Test.PersonWrapper]
starting with method caseClassParser in object Test
Parser[PersonWrapper]("kevin,66,42")
^
Erstens, warum tritt dieser divergente implizite Fehler auf?
Zweitens ist es möglich, den obigen Code zu verwenden, um eine Parser[PersonWrapper]
zu bekommen?
Sind Sie sicher, dass Sie nicht implizit im REPL-Bereich herumhängen? Ich bekomme den divergierenden impliziten Fehler nicht. –
Hmm. Nun, was für ein Ergebnis hast du mit 'Parser [PersonWrapper] (" kevin, 66,42 ")? Hier ist mein vollständiges Ergebnis: https://gist.github.com/kevinmeredith/f4995cdf3bc61907bef76182bee69b39 –