Skip to content

Instantly share code, notes, and snippets.

@RomanIakovlev
Created November 19, 2015 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RomanIakovlev/ebf3bf2cba129f25c7db to your computer and use it in GitHub Desktop.
Save RomanIakovlev/ebf3bf2cba129f25c7db to your computer and use it in GitHub Desktop.
trait Parser[A] {
def apply(s: String): Option[A]
}
import scala.util.Try
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
}
import shapeless._
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 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)
}
case class Person(name: String, age: Double)
case class Book(title: String, author: String, year: Int)
case class Country(name: String, population: Int, area: Double)
Parser[Person]("Amy,54.2")
Parser[Person]("Fred,23")
Parser[Book]("Hamlet,Shakespeare,1600")
Parser[Country]("Finland,4500000,338424")
Parser[Book]("Hamlet,Shakespeare")
case class BookBook(b1: Book, b2: Book)
Parser[BookBook]("Hamlet,Shakespeare")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment