- def decode[A: FromRecord](tsv: StringLike[_]): Seq[A] = {
- val lines = tsv.split('\n').filter(!_.isEmpty)
- val header = lines.head.split('\t').map(Symbol(_))
- val body = lines.tail.map(line => (header zip line.split('\t')).toMap)
- return body.map(implicitly[FromRecord[A]].parseRecord)
+ implicit def ToMonadErrorOps[A](m: Parser[A]) = new {
+ def handleError(f: String => Parser[A]): Parser[A]
+ = implicitly[MonadError[({type λ[String, α] = Parser[α]})#λ, String]].handleError(m)(f)
+ }
+
+ implicit def ToMonadErrorIdOps(e: String) = new {
+ def raiseError[A]: Parser[A]
+ = implicitly[MonadError[({type λ[String, α] = Parser[α]})#λ, String]].raiseError(e)
+ }
+
+ type Header = Seq[Symbol]
+
+ case class Field(value: String) {
+ def parseField[A: FromField]
+ = implicitly[FromField[A]].parseField(Field(value))
+ }
+
+ case class Record(value: Map[Symbol, Field]) {
+ def parseRecord[A: FromRecord]
+ = implicitly[FromRecord[A]].parseRecord(Record(value))
+
+ def lookup[A: FromField](name: Symbol): Parser[A]
+ = value.get(name).fold(("no field named " + name.name).raiseError[A])(_.parseField[A])
+
+ def lookup[A: FromField](name: Symbol, default: String): Parser[A]
+ = value.get(name).getOrElse(Field(default)).parseField[A]
+ }
+
+ type Failure[ F[_], R] = String => F[R]
+ type Success[A, F[_], R] = A => F[R]
+
+ trait Parser[+A] {
+ def runParser[F[_], R](kf: Failure[F, R], ks: Success[A, F, R]): F[R]
+ }
+
+ def runParser[A](p: Parser[A]): Either[String, A] = {
+ type F[R] = Either[String, R]
+ def left (e: String): F[A] = Left(e)
+ def right(x: A ): F[A] = Right(x)
+ return p.runParser(left, right)