]> gitweb @ CieloNegro.org - task-reporter.git/blob - src/main/scala/jp/ymir/taskReporter/core/TSV.scala
MonadError
[task-reporter.git] / src / main / scala / jp / ymir / taskReporter / core / TSV.scala
1 package jp.ymir.taskReporter.core
2 import scala.collection._
3 import scala.collection.immutable.StringLike
4 import scala.language.higherKinds
5 import scalaz._
6
7 object TSV {
8   type Header = Seq[Symbol]
9   type Field  = String
10   type Record = Map[Symbol, Field]
11
12   // ---
13   type Failure[   F[_, _], E, R] = E => F[E, R]
14   type Success[A, F[_, _], E, R] = A => F[E, R]
15
16   trait Parser[E, A] {
17     def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[A, F, E, R]): F[E, R]
18   }
19
20   implicit def ParserFunctor[E] = new Functor[({type λ[α] = Parser[E, α]})#λ] {
21     def map[A, B](m: Parser[E, A])(f: A => B) = new Parser[E, B] {
22       def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[B, F, E, R]): F[E, R] = {
23         def ks_(a: A) = ks(f(a))
24         return m.runParser(kf, ks_)
25       }
26     }
27   }
28
29   implicit def ParserApplicative[E] = new Applicative[({type λ[α] = Parser[E, α]})#λ] {
30     def point[A](a: => A) = new Parser[E, A] {
31       def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[A, F, E, R]): F[E, R]
32         = ks(a)
33     }
34     def ap[A, B](m: => Parser[E, A])(fm: => Parser[E, A => B]) = new Parser[E, B] {
35       def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[B, F, E, R]): F[E, R] = {
36         def ks_(f: A => B): F[E, R] = {
37           def ks__(a: A) = ks(f(a))
38           return m.runParser(kf, ks__)
39         }
40         return fm.runParser(kf, ks_)
41       }
42     }
43   }
44
45   implicit def ParserMonad[E] = new Monad[({type λ[α] = Parser[E, α]})#λ] {
46     def point[A](a: => A)
47       = implicitly[Applicative[({type λ[α] = Parser[E, α]})#λ]].point(a)
48
49     def bind[A, B](m: Parser[E, A])(f: A => Parser[E, B]) = new Parser[E, B] {
50       def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[B, F, E, R]): F[E, R] = {
51         def ks_(a: A) = f(a).runParser(kf, ks)
52         return m.runParser(kf, ks_)
53       }
54     }
55   }
56
57   implicit def ParserMonadError[E] = new MonadError[Parser, E] {
58     def point[A](a: => A)
59       = implicitly[Applicative[({type λ[α] = Parser[E, α]})#λ]].point(a)
60
61     def bind[A, B](m: Parser[E, A])(f: A => Parser[E, B])
62       = implicitly[Monad[({type λ[α] = Parser[E, α]})#λ]].bind(m)(f)
63
64     def handleError[A](m: Parser[E, A])(f: E => Parser[E, A]) = new Parser[E, A] {
65       def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[A, F, E, R]): F[E, R] = {
66         def kf_(e: E) = f(e).runParser(kf, ks)
67         return m.runParser(kf_, ks)
68       }
69     }
70
71     def raiseError[A](e: E) = new Parser[E, A] {
72       def runParser[F[_, _], R](kf: Failure[F, E, R], ks: Success[A, F, E, R]): F[E, R]
73         = kf(e)
74     }
75   }
76
77   def runParser[E, A](p: Parser[E, A]): Either[E, A] = {
78     def left (e: E): Either[E, A] = Left(e)
79     def right(x: A): Either[E, A] = Right(x)
80     return p.runParser(left, right)
81   }
82   // ---
83
84   def decode[A: FromRecord](tsv: StringLike[_]): Seq[A] = {
85     val lines  = tsv.split('\n').filter(!_.isEmpty)
86     val header = lines.head.split('\t').map(Symbol(_))
87     val body   = lines.tail.map(line => (header zip line.split('\t')).toMap)
88     return body.map(implicitly[FromRecord[A]].parseRecord)
89   }
90
91   trait FromRecord[A] {
92     def parseRecord(r: Record): A
93   }
94
95   trait FromField[A] {
96     def parseField(f: Field): A
97   }
98   def parseField[A: FromField](f: Field): A
99     = implicitly[FromField[A]].parseField(f)
100
101   trait ToRecord[A] {
102     def toRecord(a: A): Record
103   }
104
105   trait ToField[A] {
106     def toField(a: A): Field
107   }
108
109   // Option[A]
110   implicit def OptionFromField[A: FromField] = new FromField[Option[A]] {
111     def parseField(f: Field): Option[A] = {
112       if (f.isEmpty) {
113         return None
114       }
115       else {
116         return Some(implicitly[FromField[A]].parseField(f))
117       }
118     }
119   }
120
121   // String
122   implicit def StringFromField = new FromField[String] {
123     def parseField(f: Field): String = f
124   }
125
126   // Int
127   implicit def IntFromField = new FromField[Int] {
128     def parseField(f: Field): Int = f.toInt
129   }
130 }