Created
November 19, 2015 15:16
-
-
Save RomanIakovlev/ebf3bf2cba129f25c7db to your computer and use it in GitHub Desktop.
This file contains 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
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