http://github.com/scalaz/scalaz
Scala | 109 lines | 48 code | 17 blank | 44 comment | 4 complexity | c3508c9eef16e0feddb0c35c240e77cb MD5 | raw file
```  1package scalaz
2
3////
4/**
5 * Monad, an [[scalaz.Applicative]] that also supports [[scalaz.Bind]],
6 * circumscribed by the monad laws.
7 *
9 */
10////
11trait Monad[F[_]] extends Applicative[F] with Bind[F] { self =>
12  ////
13
14  override def map[A,B](fa: F[A])(f: A => B) = bind(fa)(a => point(f(a)))
15
16  /**
17   * Execute an action repeatedly as long as the given `Boolean` expression
18   * returns `true`. The condition is evaluated before the loop body.
19   * Collects the results into an arbitrary `MonadPlus` value, such as a `List`.
20   */
21  def whileM[G[_], A](p: F[Boolean], body: => F[A])(implicit G: MonadPlus[G]): F[G[A]] = {
22    val f = Need(body)
23    ifM(p, bind(f.value)(x => map(whileM(p, f.value))(xs => G.plus(G.point(x), xs))), point(G.empty))
24  }
25
26  /**
27   * Execute an action repeatedly as long as the given `Boolean` expression
28   * returns `true`. The condition is evaluated before the loop body.
30   */
31  def whileM_[A](p: F[Boolean], body: => F[A]): F[Unit] = {
32    val f = Need(body)
33    ifM(p, bind(f.value)(_ => whileM_(p, f.value)), point(()))
34  }
35
36  /**
37   * Execute an action repeatedly until the `Boolean` condition returns `true`.
38   * The condition is evaluated after the loop body. Collects results into an
39   * arbitrary `MonadPlus` value, such as a `List`.
40   */
41  def untilM[G[_], A](f: F[A], cond: => F[Boolean])(implicit G: MonadPlus[G]): F[G[A]] = {
42    val p = Need(cond)
43    bind(f)(x => map(whileM(map(p.value)(!_), f))(xs => G.plus(G.point(x), xs)))
44  }
45
46  /**
47   * Execute an action repeatedly until the `Boolean` condition returns `true`.
48   * The condition is evaluated after the loop body. Discards results.
49   */
50  def untilM_[A](f: F[A], cond: => F[Boolean]): F[Unit] = {
51    val p = Need(cond)
52    bind(f)(_ => whileM_(map(p.value)(!_), f))
53  }
54
55  /**
56   * Execute an action repeatedly until its result fails to satisfy the given predicate
57   * and return that result, discarding all others.
58   */
59  def iterateWhile[A](f: F[A])(p: A => Boolean): F[A] =
60    bind(f)(y => if (p(y)) iterateWhile(f)(p) else point(y))
61
62  /**
63   * Execute an action repeatedly until its result satisfies the given predicate
64   * and return that result, discarding all others.
65   */
66  def iterateUntil[A](f: F[A])(p: A => Boolean): F[A] =
67    bind(f)(y => if (p(y)) point(y) else iterateUntil(f)(p))
68
69  /**The product of Monad `F` and `G`, `[x](F[x], G[x]])`, is a Monad */
72      def F = self
73      def G = G0
74    }
75
76  trait MonadLaw extends ApplicativeLaw with BindLaw {
77    /** Lifted `point` is a no-op. */
78    def rightIdentity[A](a: F[A])(implicit FA: Equal[F[A]]): Boolean = FA.equal(bind(a)(point(_: A)), a)
79    /** Lifted `f` applied to pure `a` is just `f(a)`. */
80    def leftIdentity[A, B](a: A, f: A => F[B])(implicit FB: Equal[F[B]]): Boolean = FB.equal(bind(point(a))(f), f(a))
81  }
83  ////
86}
87
90
91  import Isomorphism._
92
95      override def G: Monad[G] = E
96      override def iso: F <~> G = D
97    }
98
99  ////
100
101  ////
102}
103