import scalaz._
import Scalaz._
-object TSV {
+abstract class TSVTypes {
implicit val ParserFunctor = new Functor[Parser] {
def map[A, B](m: Parser[A])(f: A => B) = new Parser[B] {
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]
def this(msg: String, cause: Throwable) = this(new RuntimeException(msg, cause))
}
- 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 => Record((header zip line.split('\t').map { Field(_) }).toMap))
- return body.map { r =>
- runParser(r.parseRecord[A]) match {
- case Right(a) => a
- case Left(e) => throw new DecodeFailedException(e)
- }
- }
- }
-
// Option[A]
implicit def OptionFromField[A: FromField] = new FromField[Option[A]] {
def parseField(f: Field): Parser[Option[A]] = {
}
}
}
+
+trait TSVFunctions extends TSVTypes {
+ def decode[A: FromRecord](tsv: StringLike[_]): Seq[A] = {
+ val lines = tsv.split('\n').filter(!_.isEmpty)
+ val header = lines.head.split('\t').map(Symbol(_))
+ val records = lines.tail.map(line => Record((header zip line.split('\t').map { Field(_) }).toMap))
+ return records.map { r =>
+ runParser(r.parseRecord[A]) match {
+ case Right(a) => a
+ case Left(e) => throw new DecodeFailedException(e)
+ }
+ }
+ }
+}
+
+object TSV extends TSVTypes with TSVFunctions