direct implementation of apply2 and resulting cleanups in usages

This commit is contained in:
Mark Harrah
2014-01-14 16:18:28 -05:00
parent 4b0123f9ec
commit 78eefecedd
3 changed files with 12 additions and 5 deletions
@@ -28,7 +28,8 @@ object ParserInstance extends Instance
{
import sbt.Classes.Applicative
private[this] implicit val parserApplicative: Applicative[M] = new Applicative[M]{
def apply[S,T](f: M[S => T], v: M[S]): M[T] = s => (f(s) ~ v(s)) map { case (a,b) => a(b) }
def apply[S,T](f: M[S => T], v: M[S]): M[T] = apply2(f,v)( (f,v) => f(v))
def apply2[S,T,U](m: M[S], n: M[T])(f: (S,T) => U): M[U] = s => (m(s) ~ n(s)) map { case (a,b) => f(a,b) }
def pure[S](s: => S) = const(Parser.success(s))
def map[S, T](f: S => T, v: M[S]) = s => v(s).map(f)
}
@@ -4,6 +4,7 @@ object Classes
{
trait Applicative[M[_]]
{
def apply2[S,T,U](s: M[S], t: M[T])(f: (S,T) => U): M[U]
def apply[S,T](f: M[S => T], v: M[S]): M[T]
def pure[S](s: => S): M[S]
def map[S, T](f: S => T, v: M[S]): M[T]
@@ -13,15 +14,21 @@ object Classes
def flatten[T](m: M[M[T]]): M[T]
}
implicit val optionMonad: Monad[Option] = new Monad[Option] {
def apply[S,T](f: Option[S => T], v: Option[S]) = (f, v) match { case (Some(fv), Some(vv)) => Some(fv(vv)); case _ => None }
def apply[S,T](f: Option[S => T], v: Option[S]) = apply2(f, v)(app2)
def apply2[S,T,U](s: Option[S], t: Option[T])(f: (S,T) => U): Option[U] = (s, t) match {
case (Some(sv), Some(tv)) => Some(f(sv,tv))
case _ => None
}
def pure[S](s: => S) = Some(s)
def map[S, T](f: S => T, v: Option[S]) = v map f
def flatten[T](m: Option[Option[T]]): Option[T] = m.flatten
}
implicit val listMonad: Monad[List] = new Monad[List] {
def apply[S,T](f: List[S => T], v: List[S]) = for(fv <- f; vv <- v) yield fv(vv)
def apply[S,T](f: List[S => T], v: List[S]) = apply2(f, v)(app2)
def apply2[S,T,U](s: List[S], t: List[T])(f: (S,T) => U) = for(sv <- s; tv <- t) yield f(sv,tv)
def pure[S](s: => S) = s :: Nil
def map[S, T](f: S => T, v: List[S]) = v map f
def flatten[T](m: List[List[T]]): List[T] = m.flatten
}
private[this] def app2[S,T] = (f: S => T,v: S) => f(v)
}
@@ -37,8 +37,7 @@ final case class KCons[H, +T <: KList[M], +M[_]](head: M[H], tail: T) extends KL
def traverse[N[_], P[_]](f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[Transform[P]] =
{
val tt: N[tail.Transform[P]] = tail.traverse[N,P](f)
val g = (t: tail.Transform[P]) => (h: P[H]) => KCons(h, t)
np.apply(np.map(g, tt), f(head))
np.apply2(f(head), tt)( (h,t) => KCons(h,t))
}
def :^:[A,N[x] >: M[x]](h: N[A]) = KCons(h, this)
override def foldr[T](f: (M[_], T) => T, init: T): T = f(head, tail.foldr(f, init))