Last active
July 31, 2016 02:38
-
-
Save kevinmeredith/f4995cdf3bc61907bef76182bee69b39 to your computer and use it in GitHub Desktop.
http://stackoverflow.com/questions/38679873/diverging-implicits-for-case-class-w-case-class-argument
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package net | |
| import scala.util._ | |
| import shapeless._ | |
| object Test { | |
| case class Person(name: String, age: Double) | |
| case class PersonWrapper(person: Person, x: Int) | |
| 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 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) | |
| } | |
| } | |
| /* | |
| scala> import net.Test._ | |
| import net.Test._ | |
| 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") | |
| ^ | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment