Skip to content

Commit

Permalink
Merge branch 'master' into scala-2.9.x
Browse files Browse the repository at this point in the history
  • Loading branch information
retronym committed Apr 26, 2011
2 parents bc96b63 + 160533f commit 22de486
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 18 deletions.
4 changes: 3 additions & 1 deletion core/src/main/scala/scalaz/Applicative.scala
Expand Up @@ -16,13 +16,15 @@ package scalaz
*/
trait Applicative[Z[_]] extends Pointed[Z] with Apply[Z] {
override def fmap[A, B](fa: Z[A], f: A => B): Z[B] = this(pure(f), fa)
override def apply[A, B](f: Z[A => B], a: Z[A]): Z[B] = liftA2(f, a, (_:A => B)(_: A))
def liftA2[A, B, C](a: Z[A], b: Z[B], f: (A, B) => C): Z[C] = apply(fmap(a, f.curried), b)
}

trait ApplicativeLow {
implicit def applicative[Z[_]](implicit p: Pure[Z], a: Apply[Z]): Applicative[Z] = new Applicative[Z] {
def pure[A](a: => A) = p.pure(a)

def apply[A, B](f: Z[A => B], x: Z[A]) = a(f, x)
override def apply[A, B](f: Z[A => B], x: Z[A]) = a(f, x)
}
}

Expand Down
46 changes: 45 additions & 1 deletion core/src/main/scala/scalaz/ApplicativeBuilder.scala
Expand Up @@ -48,7 +48,7 @@ final class ApplicativeBuilder[M[_], A, B](a: M[A], b: M[B]) {

def |@|[G](g: M[G]) = new ApplicativeBuilder7[G](g)

class ApplicativeBuilder7[G](g: M[G]) {
final class ApplicativeBuilder7[G](g: M[G]) {
def apply[H](f: (A, B, C, D, E, F, G) => H)(implicit t: Functor[M], ap: Apply[M]): M[H] = ap(ap(ap(ap(ap(ap(t.fmap(a, f.curried), b), c), d), e), ff), g)

def tupled(implicit t: Functor[M], ap: Apply[M]): M[(A, B, C, D, E, F, G)] = apply(Tuple7.apply)
Expand All @@ -61,6 +61,50 @@ final class ApplicativeBuilder[M[_], A, B](a: M[A], b: M[B]) {
def apply[I](f: (A, B, C, D, E, F, G, H) => I)(implicit t: Functor[M], ap: Apply[M]): M[I] = ap(ap(ap(ap(ap(ap(ap(t.fmap(a, f.curried), b), c), d), e), ff), g), h)

def tupled(implicit t: Functor[M], ap: Apply[M]): M[(A, B, C, D, E, F, G, H)] = apply(Tuple8.apply)

def [I](i: M[I]) = new ApplicativeBuilder9[I](i)

def |@|[I](i: M[I]) = new ApplicativeBuilder9[I](i)

final class ApplicativeBuilder9[I](i: M[I]) {
def apply[J](f: (A, B, C, D, E, F, G, H, I) => J)(implicit t: Functor[M], ap: Apply[M]): M[J] =
ap(ap(ap(ap(ap(ap(ap(ap(t.fmap(a, f.curried), b), c), d), e), ff), g), h), i)

def tupled(implicit t: Functor[M], ap: Apply[M]): M[(A, B, C, D, E, F, G, H, I)] = apply(Tuple9.apply)

def [J](j: M[J]) = new ApplicativeBuilder10[J](j)

def |@|[J](j: M[J]) = new ApplicativeBuilder10[J](j)

final class ApplicativeBuilder10[J](j: M[J]) {
def apply[K](f: (A, B, C, D, E, F, G, H, I, J) => K)(implicit t: Functor[M], ap: Apply[M]): M[K] =
ap(ap(ap(ap(ap(ap(ap(ap(ap(t.fmap(a, f.curried), b), c), d), e), ff), g), h), i), j)

def tupled(implicit t: Functor[M], ap: Apply[M]): M[(A, B, C, D, E, F, G, H, I, J)] = apply(Tuple10.apply)

def [K](k: M[K]) = new ApplicativeBuilder11[K](k)

def |@|[K](k: M[K]) = new ApplicativeBuilder11[K](k)

final class ApplicativeBuilder11[K](k: M[K]) {
def apply[L](f: (A, B, C, D, E, F, G, H, I, J, K) => L)(implicit t: Functor[M], ap: Apply[M]): M[L] =
ap(ap(ap(ap(ap(ap(ap(ap(ap(ap(t.fmap(a, f.curried), b), c), d), e), ff), g), h), i), j), k)

def tupled(implicit t: Functor[M], ap: Apply[M]): M[(A, B, C, D, E, F, G, H, I, J, K)] = apply(Tuple11.apply)

def [L](l: M[L]) = new ApplicativeBuilder12[L](l)

def |@|[L](l: M[L]) = new ApplicativeBuilder12[L](l)

final class ApplicativeBuilder12[L](l: M[L]) {
def apply[MM](f: (A, B, C, D, E, F, G, H, I, J, K, L) => MM)(implicit t: Functor[M], ap: Apply[M]): M[MM] =
ap(ap(ap(ap(ap(ap(ap(ap(ap(ap(ap(t.fmap(a, f.curried), b), c), d), e), ff), g), h), i), j), k), l)

def tupled(implicit t: Functor[M], ap: Apply[M]): M[(A, B, C, D, E, F, G, H, I, J, K, L)] = apply(Tuple12.apply)
}
}
}
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/scalaz/Comp.scala
Expand Up @@ -10,6 +10,6 @@ object Comp {
implicit def CompApplicative[M[_], N[_]](implicit ma: Applicative[M], na: Applicative[N]): Applicative[({type λ[α]=M[N[α]]})#λ] = new Applicative[({type λ[α]=M[N[α]]})#λ] {
def pure[A](a: => A): M[N[A]] = a.η[N].η[M]

def apply[A, B](f: M[N[A => B]], a: M[N[A]]): M[N[B]] = (a <**> f)(_ <*> _)
override def apply[A, B](f: M[N[A => B]], a: M[N[A]]): M[N[B]] = (a <**> f)(_ <*> _)
}
}
}
6 changes: 3 additions & 3 deletions core/src/main/scala/scalaz/Identity.scala
Expand Up @@ -70,11 +70,11 @@ sealed trait Identity[A] extends Equals with IdentitySugar[A] {
case Some((b, a)) => b.η ⊹ a.unfold(f)
}

def replicate[M[_]](n: Int)(implicit p: Pure[M], m: Monoid[M[A]]): M[A] = {
def replicate[M[_]](n: Int, f: A => A = a => a)(implicit p: Pure[M], m: Monoid[M[A]]): M[A] = {
@tailrec
def replicate0(accum: M[A], n: Int): M[A] = if (n > 0) replicate0(accum ⊹ value.η, n - 1) else accum
def replicate0(accum: M[A], n: Int, a: A): M[A] = if (n > 0) replicate0(accum ⊹ a.η, n - 1, f(a)) else accum

replicate0(∅, n)
replicate0(∅, n, value)
}

def repeat[M[_]](implicit p: Pure[M], m: Monoid[M[A]]): M[A] = value.η ⊹ repeat
Expand Down
5 changes: 5 additions & 0 deletions core/src/main/scala/scalaz/IntW.scala
Expand Up @@ -6,6 +6,11 @@ sealed trait IntW extends PimpedType[Int] {
def : IntMultiplication = multiplication(value)

def ordering: Ordering = if (value < 0) LT else if (value > 0) GT else EQ

def times[M:Monoid](m: M): M = {
def timesPrime(a: M, n: Int): M = if (n > 0) timesPrime(m |+| a, n - 1) else a
timesPrime(mzero, value)
}
}

trait Ints {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/scalaz/ListT.scala
Expand Up @@ -32,7 +32,7 @@ sealed class ListT[M[_],A](val step : M[ListT.Step[A, ListT[M,A]]]) {
)
def takeWhile(p: A => Boolean)(implicit M: Functor[M]): ListT[M,A] = ListT[M,A](
step map {
case Yield(a,as) => if (!p(a)) Skip(as takeWhile p) else Yield(a,as)
case Yield(a,as) => if (!p(a)) Done else Yield(a,as takeWhile p)
case Skip(as) => Skip(as takeWhile p)
case Done => Done
}
Expand Down
14 changes: 13 additions & 1 deletion core/src/main/scala/scalaz/MA.scala
Expand Up @@ -79,11 +79,14 @@ trait MA[M[_], A] extends PimpedType[M[A]] with MASugar[M, A] {

def >>=|[B](f: => M[B])(implicit b: Bind[M]): M[B] = >>=((x:A) => f)

/** Alias for >>=| */
def >|>[B](f: => M[B])(implicit b: Bind[M]): M[B] = >>=|(f)

def flatMap[B](f: A => M[B])(implicit b: Bind[M]): M[B] = b.bind(value, f)

def join[B](implicit m: A <:< M[B], b: Bind[M]): M[B] = >>=(m)

def forever[B](implicit b: Bind[M]): M[B] = value | value.forever
def forever[B](implicit b: Bind[M]): M[B] = value >|> value.forever

def <+>(z: => M[A])(implicit p: Plus[M]): M[A] = p.plus(value, z)

Expand Down Expand Up @@ -143,6 +146,9 @@ trait MA[M[_], A] extends PimpedType[M[A]] with MASugar[M, A] {

def stream(implicit r: Foldable[M]): Stream[A] = foldr(Stream.empty[A])(Stream.cons(_, _))

def asStream[B](f: Stream[A] => Stream[B])(implicit r: Foldable[M], m: Monoid[M[B]], p: Pure[M]): M[B] =
f(stream).foldr(m.zero)(p.pure(_) |+| _)

def !!(n: Int)(implicit r: Foldable[M]): A = stream(r)(n)

def !(n: Int)(implicit i: Index[M]): Option[A] = i.index(value, n)
Expand Down Expand Up @@ -260,6 +266,12 @@ trait MA[M[_], A] extends PimpedType[M[A]] with MASugar[M, A] {
if (n <= 0) ∅[N[A]].η[M]
else value ∗ (a => replicateM[N](n - 1) ∘ (a +>: _) )

def replicateM_(n: Int)(implicit m: Monad[M]): M[Unit] = {
def replicateM__(a: M[Unit], i: Int): M[Unit] =
if (i > 0) replicateM__(value >|> a, i - 1) else a
replicateM__(().pure[M], n)
}

def zipWithA[F[_], B, C](b: M[B])(f: (A, B) => F[C])(implicit a: Applicative[M], t: Traverse[M], z: Applicative[F]): F[M[C]] =
(b <*> (a.fmap(value, f.curried))).sequence[F, C]

Expand Down
6 changes: 6 additions & 0 deletions core/src/main/scala/scalaz/Monoid.scala
Expand Up @@ -25,4 +25,10 @@ object Monoid extends MonoidLow {
import Zero._

implicit def EitherLeftMonoid[A, B](implicit bz: Zero[B]) = monoid[Either.LeftProjection[A, B]](EitherLeftSemigroup, EitherLeftZero[A, B](bz))

/** A monoid for sequencing Applicative effects. */
def liftMonoid[F[_], M](implicit m: Monoid[M], a: Applicative[F]): Monoid[F[M]] = new Monoid[F[M]] {
val zero: F[M] = a.pure(m.zero)
def append(x: F[M], y: => F[M]): F[M] = a.liftA2(x, y, (m1: M, m2: M) => m.append(m1, m2))
}
}
2 changes: 1 addition & 1 deletion core/src/main/scala/scalaz/Prod.scala
Expand Up @@ -6,7 +6,7 @@ object Prod {

def pure[A](a: => A) = (a.η[M], a.η[N])

def apply[A, B](f: (M[A => B], N[A => B]), a: (M[A], N[A])) = {
override def apply[A, B](f: (M[A => B], N[A => B]), a: (M[A], N[A])) = {
lazy val fv = f
lazy val av = a
(av._1 <*> fv._1, av._2 <*> fv._2)
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/scalaz/StreamT.scala
Expand Up @@ -43,7 +43,7 @@ sealed class StreamT[M[_],A](stepper: => M[StreamT.Step[A, StreamT[M,A]]]) {
)
def takeWhile(p: A => Boolean)(implicit M: Functor[M]): StreamT[M,A] = StreamT[M,A](
step map {
case Yield(a,as) => if (!p(a)) Skip(as takeWhile p) else Yield(a,as)
case Yield(a,as) => if (!p(a)) Done else Yield(a,as takeWhile p)
case Skip(as) => Skip(as takeWhile p)
case Done => Done
}
Expand Down
13 changes: 6 additions & 7 deletions core/src/main/scala/scalaz/effects/package.scala
Expand Up @@ -28,12 +28,6 @@ package object effects {
ans
})

/** A monoid for sequencing ST effects. */
implicit def stMonoid[S]: Monoid[ST[S, Unit]] = new Monoid[ST[S, Unit]] {
val zero: ST[S, Unit] = returnST(())
def append(x: ST[S, Unit], y: => ST[S, Unit]) = x >>=| y
}

/** Accumulates an integer-associated list into an immutable array. */
def accumArray[F[_]:Foldable, A: Manifest, B](size: Int, f: (A, B) => A, z: A, ivs: F[(Int, B)]): ImmutableArray[A] = {
type STA[S] = ST[S, ImmutableArray[A]]
Expand All @@ -46,6 +40,11 @@ package object effects {
})
}

implicit def stMonoid[S, A: Monoid]: Monoid[ST[S, A]] = Monoid.liftMonoid[({ type λ[A] = ST[S, A] })#λ, A]
implicit def ioMonoid[A: Monoid]: Monoid[IO[A]] = Monoid.liftMonoid

implicit def stApplicative[S]: Applicative[({ type λ[A] = ST[S, A] })#λ] = stMonad[S]

implicit def stMonad[S]: Monad[({ type λ[A] = ST[S, A] })#λ] = new Monad[({ type λ[A] = ST[S, A] })#λ] {
def pure[A](a: => A) = returnST(a)
def bind[A, B](m: ST[S, A], f: A => ST[S, B]): ST[S, B] = m flatMap f
Expand All @@ -66,7 +65,7 @@ package object effects {
def putStr(s: String): IO[Unit] = IO(rw => (rw, { print(s); () }))
def putStrLn(s: String): IO[Unit] = IO((rw => (rw, { println(s); () })))
def readLn: IO[String] = IO(rw => (rw, readLine))
def print[A](a: A): IO[Unit] = IO(rw => (rw, { Predef.print(a); () }))
def putOut[A](a: A): IO[Unit] = IO(rw => (rw, { print(a); () }))

// Mutable variables in the IO monad
def newIORef[A](a: => A) = stToIO(newVar(a)) >>= (v => new IORef(v).pure[IO])
Expand Down

0 comments on commit 22de486

Please sign in to comment.