From: PHO Date: Tue, 14 Oct 2014 07:28:38 +0000 (+0900) Subject: wip X-Git-Url: https://git.cielonegro.org/gitweb.cgi?a=commitdiff_plain;h=9e30a515d63c28f15fed2cc1769581e9888e4ed4;p=task-reporter.git wip --- diff --git a/src/main/scala/jp/ymir/taskReporter/core/TSV.scala b/src/main/scala/jp/ymir/taskReporter/core/TSV.scala index 541104f..5b2d261 100644 --- a/src/main/scala/jp/ymir/taskReporter/core/TSV.scala +++ b/src/main/scala/jp/ymir/taskReporter/core/TSV.scala @@ -2,7 +2,10 @@ package jp.ymir.taskReporter.core import scala.collection._ import scala.collection.immutable.StringLike import scala.language.higherKinds +import scala.language.implicitConversions +import scala.language.reflectiveCalls import scalaz._ +import Scalaz._ object TSV { type Header = Seq[Symbol] @@ -10,30 +13,30 @@ object TSV { type Record = Map[Symbol, Field] // --- - type Failure[ F[_, _], E, R] = E => F[E, R] - type Success[A, F[_, _], E, R] = A => F[E, R] + type Failure[ F[_], R] = String => F[R] + type Success[A, F[_], R] = A => F[R] - trait Parser[E, A] { - def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[A, F, E, R]): F[E, R] + trait Parser[A] { + def runParser[F[_], R](kf: Failure[F, R], ks: Success[A, F, R]): F[R] } - implicit def ParserFunctor[E] = new Functor[({type λ[α] = Parser[E, α]})#λ] { - def map[A, B](m: Parser[E, A])(f: A => B) = new Parser[E, B] { - def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[B, F, E, R]): F[E, R] = { + implicit def ParserFunctor = new Functor[Parser] { + def map[A, B](m: Parser[A])(f: A => B) = new Parser[B] { + def runParser[F[_], R](kf: Failure[F, R], ks: Success[B, F, R]): F[R] = { def ks_(a: A) = ks(f(a)) return m.runParser(kf, ks_) } } } - implicit def ParserApplicative[E] = new Applicative[({type λ[α] = Parser[E, α]})#λ] { - def point[A](a: => A) = new Parser[E, A] { - def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[A, F, E, R]): F[E, R] + implicit def ParserApplicative = new Applicative[Parser] { + def point[A](a: => A) = new Parser[A] { + def runParser[F[_], R](kf: Failure[F, R], ks: Success[A, F, R]): F[R] = ks(a) } - def ap[A, B](m: => Parser[E, A])(fm: => Parser[E, A => B]) = new Parser[E, B] { - def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[B, F, E, R]): F[E, R] = { - def ks_(f: A => B): F[E, R] = { + def ap[A, B](m: => Parser[A])(fm: => Parser[A => B]) = new Parser[B] { + def runParser[F[_], R](kf: Failure[F, R], ks: Success[B, F, R]): F[R] = { + def ks_(f: A => B): F[R] = { def ks__(a: A) = ks(f(a)) return m.runParser(kf, ks__) } @@ -42,41 +45,42 @@ object TSV { } } - implicit def ParserMonad[E] = new Monad[({type λ[α] = Parser[E, α]})#λ] { - def point[A](a: => A) - = implicitly[Applicative[({type λ[α] = Parser[E, α]})#λ]].point(a) + implicit def ParserMonad = new Monad[Parser] { + def point[A](a: => A) = a.point[Parser] - def bind[A, B](m: Parser[E, A])(f: A => Parser[E, B]) = new Parser[E, B] { - def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[B, F, E, R]): F[E, R] = { + def bind[A, B](m: Parser[A])(f: A => Parser[B]) = new Parser[B] { + def runParser[F[_], R](kf: Failure[F, R], ks: Success[B, F, R]): F[R] = { def ks_(a: A) = f(a).runParser(kf, ks) return m.runParser(kf, ks_) } } } - implicit def ParserMonadError[E] = new MonadError[Parser, E] { - def point[A](a: => A) - = implicitly[Applicative[({type λ[α] = Parser[E, α]})#λ]].point(a) + implicit def ParserMonadError = new MonadError[({type λ[String, α] = Parser[α]})#λ, String] { + def point[A](a: => A) = a.point[Parser] + def bind[A, B](m: Parser[A])(f: A => Parser[B]) = m.flatMap(f) - def bind[A, B](m: Parser[E, A])(f: A => Parser[E, B]) - = implicitly[Monad[({type λ[α] = Parser[E, α]})#λ]].bind(m)(f) - - def handleError[A](m: Parser[E, A])(f: E => Parser[E, A]) = new Parser[E, A] { - def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[A, F, E, R]): F[E, R] = { - def kf_(e: E) = f(e).runParser(kf, ks) + def handleError[A](m: Parser[A])(f: String => Parser[A]) = new Parser[A] { + def runParser[F[_], R](kf: Failure[F, R], ks: Success[A, F, R]): F[R] = { + def kf_(e: String) = f(e).runParser(kf, ks) return m.runParser(kf_, ks) } } - def raiseError[A](e: E) = new Parser[E, A] { - def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[A, F, E, R]): F[E, R] + def raiseError[A](e: String) = new Parser[A] { + def runParser[F[_], R](kf: Failure[F, R], ks: Success[A, F, R]): F[R] = kf(e) } } + implicit def ToMonadErrorIdOps(e: String) = new { + def raiseError[A]: Parser[A] + = implicitly[MonadError[({type λ[String, α] = Parser[α]})#λ, String]].raiseError(e) + } - def runParser[E, A](p: Parser[E, A]): Either[E, A] = { - def left (e: E): Either[E, A] = Left(e) - def right(x: A): Either[E, A] = Right(x) + 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) } // --- @@ -93,10 +97,12 @@ object TSV { } trait FromField[A] { - def parseField(f: Field): A + def parseField(f: Field): Parser[A] + } + implicit def toFromFieldOps(f: Field) = new { + def parseField[A: FromField] + = implicitly[FromField[A]].parseField(f) } - def parseField[A: FromField](f: Field): A - = implicitly[FromField[A]].parseField(f) trait ToRecord[A] { def toRecord(a: A): Record @@ -108,23 +114,31 @@ object TSV { // Option[A] implicit def OptionFromField[A: FromField] = new FromField[Option[A]] { - def parseField(f: Field): Option[A] = { + def parseField(f: Field): Parser[Option[A]] = { if (f.isEmpty) { - return None + return (None : Option[A]).point[Parser] } else { - return Some(implicitly[FromField[A]].parseField(f)) + f.parseField[A].map { Some(_) } } } } // String implicit def StringFromField = new FromField[String] { - def parseField(f: Field): String = f + def parseField(f: Field): Parser[String] = f.point[Parser] } // Int implicit def IntFromField = new FromField[Int] { - def parseField(f: Field): Int = f.toInt + def parseField(f: Field): Parser[Int] = { + try { + f.toInt.point[Parser] + } + catch { + case e: NumberFormatException => + e.getMessage().raiseError[Int] + } + } } }