PageRenderTime 41ms CodeModel.GetById 1ms app.highlight 34ms RepoModel.GetById 1ms app.codeStats 0ms

/core/src/main/scala/scalaz/OptionT.scala

http://github.com/scalaz/scalaz
Scala | 320 lines | 225 code | 80 blank | 15 comment | 0 complexity | 2ee50e1178f2cf44fb7e6ea8b2034436 MD5 | raw file
  1package scalaz
  2
  3import std.option.{optionInstance, none, some}
  4
  5/**
  6 * OptionT monad transformer.
  7 */
  8final case class OptionT[F[_], A](run: F[Option[A]]) {
  9  self =>
 10
 11  def map[B](f: A => B)(implicit F: Functor[F]): OptionT[F, B] = new OptionT[F, B](mapO(_ map f))
 12
 13  def mapT[G[_], B](f: F[Option[A]] => G[Option[B]]): OptionT[G, B] =
 14    OptionT(f(run))
 15
 16  def flatMap[B](f: A => OptionT[F, B])(implicit F: Monad[F]): OptionT[F, B] = new OptionT[F, B](
 17    F.bind(self.run) {
 18      case None    => F.point(None: Option[B])
 19      case Some(z) => f(z).run
 20    }
 21  )
 22
 23  def mapF[B](f: A => F[B])(implicit F: Monad[F]): OptionT[F, B] = new OptionT[F, B](
 24    F.bind(self.run) {
 25      case None    => F.point(none[B])
 26      case Some(z) => F.map(f(z))(b => some(b))
 27    }
 28  )
 29
 30  def flatMapF[B](f: A => F[Option[B]])(implicit F: Monad[F]): OptionT[F, B] = new OptionT[F, B](
 31    F.bind(self.run) {
 32      case None    => F.point(none[B])
 33      case Some(z) => f(z)
 34    }
 35  )
 36
 37  def foldRight[Z](z: => Z)(f: (A, => Z) => Z)(implicit F: Foldable[F]): Z = {
 38    import std.option._
 39    F.foldRight[Option[A], Z](run, z)((a, b) => Foldable[Option].foldRight[A, Z](a, b)(f))
 40  }
 41
 42  def traverse[G[_], B](f: A => G[B])(implicit F: Traverse[F], G: Applicative[G]): G[OptionT[F, B]] = {
 43    import std.option._
 44    G.map(F.traverse(run)(o => Traverse[Option].traverse(o)(f)))(OptionT(_))
 45  }
 46
 47  def ap[B](f: => OptionT[F, A => B])(implicit F: Monad[F]): OptionT[F, B] =
 48    OptionT(F.bind(f.run){
 49              case None => F.point(None)
 50              case Some(ff) => F.map(run)(_ map ff)
 51            })
 52
 53  /** Apply a function in the environment of both options, containing
 54    * both `F`s.  It is not compatible with `Monad#bind`.
 55    */
 56  def app[B](f: => OptionT[F, A => B])(implicit F: Apply[F]): OptionT[F, B] =
 57    OptionT(F.apply2(f.run, run) {
 58      case (ff, aa) => optionInstance.ap(aa)(ff)
 59    })
 60
 61  def isDefined(implicit F: Functor[F]): F[Boolean] = mapO(_.isDefined)
 62
 63  def isEmpty(implicit F: Functor[F]): F[Boolean] = mapO(_.isEmpty)
 64
 65  def filter(f: A => Boolean)(implicit F: Functor[F]): OptionT[F, A] = OptionT(F.map(self.run) { _ filter f })
 66
 67  def fold[X](some: A => X, none: => X)(implicit F: Functor[F]): F[X] =
 68    mapO {
 69      case None => none
 70      case Some(a) => some(a)
 71    }
 72
 73  def getOrElse(default: => A)(implicit F: Functor[F]): F[A] = mapO(_.getOrElse(default))
 74
 75  /** Alias for `getOrElse`. */
 76  def |(default: => A)(implicit F: Functor[F]): F[A] = getOrElse(default)
 77
 78  def getOrElseF(default: => F[A])(implicit F: Monad[F]): F[A] =
 79    F.bind(self.run) {
 80      case None => default
 81      case Some(a) => F.point(a)
 82    }
 83
 84  def orZero(implicit F0: Functor[F], M0: Monoid[A]): F[A] = getOrElse(M0.zero)
 85
 86  def unary_~(implicit F0: Functor[F], M0: Monoid[A]): F[A] = orZero
 87
 88  def exists(f: A => Boolean)(implicit F: Functor[F]): F[Boolean] = mapO(_.exists(f))
 89
 90  def forall(f: A => Boolean)(implicit F: Functor[F]): F[Boolean] = mapO(_.forall(f))
 91
 92  def orElse(a: => OptionT[F, A])(implicit F: Monad[F]): OptionT[F, A] =
 93    OptionT(F.bind(run) {
 94      case None => a.run
 95      case x@Some(_) => F.point(x)
 96    })
 97
 98  def |||(a: => OptionT[F, A])(implicit F: Monad[F]): OptionT[F, A] =
 99    orElse(a)
100
101  /** @since 7.0.3 */
102  def toRight[E](e: => E)(implicit F: Functor[F]): EitherT[E, F, A] = EitherT(F.map(run)(std.option.toRight(_)(e)))
103
104  def toListT(implicit F: Functor[F]) : ListT[F, A] =  ListT[F,A](F.map(run)(IList.fromOption))
105
106  /** @since 7.0.3 */
107  def toLeft[B](b: => B)(implicit F: Functor[F]): EitherT[A, F, B] = EitherT(F.map(run)(std.option.toLeft(_)(b)))
108
109  private def mapO[B](f: Option[A] => B)(implicit F: Functor[F]) = F.map(run)(f)
110}
111
112//
113// Prioritized Implicits for type class instances
114//
115
116sealed abstract class OptionTInstances3 {
117  implicit def optionTFunctor[F[_]](implicit F0: Functor[F]): Functor[OptionT[F, *]] =
118    new OptionTFunctor[F] {
119      implicit def F: Functor[F] = F0
120    }
121}
122
123sealed abstract class OptionTInstances2 extends OptionTInstances3 {
124  implicit def optionTBindRec[F[_]](implicit F0: Monad[F], B0: BindRec[F]): BindRec[OptionT[F, *]] =
125    new OptionTBindRec[F] {
126      implicit def F = F0
127      implicit def B = B0
128    }
129}
130
131sealed abstract class OptionTInstances1 extends OptionTInstances2 {
132  implicit def optionTFoldable[F[_]](implicit F0: Foldable[F]): Foldable[OptionT[F, *]] =
133    new OptionTFoldable[F] {
134      implicit def F: Foldable[F] = F0
135    }
136
137  implicit def optionTMonadError[F[_], E](implicit F0: MonadError[F, E]): MonadError[OptionT[F, *], E] =
138    new OptionTMonadError[F, E] {
139      def F = F0
140    }
141
142  implicit def optionTAlt[F[_]](implicit F0: Monad[F]): Alt[OptionT[F, *]] =
143    new Alt[OptionT[F, *]] with OptionTApply[F] with OptionTPoint[F] {
144      def F = F0
145
146      def alt[A](a: => OptionT[F, A], b: => OptionT[F, A]): OptionT[F, A] = a orElse b
147    }
148}
149
150sealed abstract class OptionTInstances0 extends OptionTInstances1 {
151  implicit def optionTMonadPlus[F[_]](implicit F0: Monad[F]): MonadPlus[OptionT[F, *]] =
152    new OptionTMonadPlus[F] {
153      implicit def F: Monad[F] = F0
154    }
155}
156
157sealed abstract class OptionTInstances extends OptionTInstances0 {
158  implicit val optionTMonadTrans: Hoist[OptionT] = new OptionTHoist {}
159
160  implicit def optionTTraverse[F[_]](implicit F0: Traverse[F]): Traverse[OptionT[F, *]] =
161    new OptionTTraverse[F] {
162      implicit def F: Traverse[F] = F0
163    }
164
165  implicit def optionTEqual[F[_], A](implicit F0: Equal[F[Option[A]]]): Equal[OptionT[F, A]] =
166    F0.contramap((_: OptionT[F, A]).run)
167
168  implicit def optionTShow[F[_], A](implicit F0: Show[F[Option[A]]]): Show[OptionT[F, A]] =
169    Contravariant[Show].contramap(F0)(_.run)
170
171  implicit def optionTDecidable[F[_]](implicit F0: Divisible[F]): Decidable[OptionT[F, *]] =
172    new OptionTDecidable[F] {
173      implicit def F: Divisible[F] = F0
174    }
175}
176
177object OptionT extends OptionTInstances {
178  def optionT[M[_]]: λ[α => M[Option[α]]] ~> OptionT[M, *] =
179    λ[λ[α => M[Option[α]]] ~> OptionT[M, *]](
180      new OptionT(_)
181    )
182
183  def some[M[_], A](v: => A)(implicit M: Applicative[M]): OptionT[M, A] =
184    OptionT.optionT[M].apply[A](M.point(Some(v)))
185
186  def none[M[_], A](implicit M: Applicative[M]): OptionT[M, A] =
187    OptionT.optionT[M].apply[A](M.point(None))
188
189  def monadTell[F[_], W, A](implicit MT0: MonadTell[F, W]): MonadTell[OptionT[F, *], W] =
190    new OptionTMonadTell[F, W] {
191      def MT = MT0
192    }
193
194  def monadListen[F[_], W, A](implicit ML0: MonadListen[F, W]): MonadListen[OptionT[F, *], W] =
195    new OptionTMonadListen[F, W] {
196      def MT = ML0
197    }
198}
199
200//
201// Implementation traits for type class instances
202//
203
204private trait OptionTDecidable[F[_]] extends Decidable[OptionT[F, *]] {
205  implicit def F: Divisible[F]
206
207  override final def conquer[A]: OptionT[F, A] = OptionT(F.conquer)
208
209  override final def divide2[A1, A2, Z](a1: => OptionT[F, A1], a2: => OptionT[F, A2])(f: Z => (A1, A2)): OptionT[F, Z] =
210    OptionT(F.divide2(a1.run, a2.run)(z => Unzip[Option].unzip(z.map(f))))
211
212  override final def choose2[Z, A1, A2](a1: => OptionT[F, A1], a2: => OptionT[F, A2])(f: Z => A1 \/ A2): OptionT[F, Z] =
213    OptionT(
214      F.divide2(a1.run, a2.run)(_.map(f)
215        .fold[(Option[A1], Option[A2])]((Option.empty, Option.empty))(
216          _.fold(a1 => (Some(a1), Option.empty), a2 => (Option.empty, Some(a2)))
217      ))
218    )
219}
220
221private trait OptionTFunctor[F[_]] extends Functor[OptionT[F, *]] {
222  implicit def F: Functor[F]
223
224  override def map[A, B](fa: OptionT[F, A])(f: A => B): OptionT[F, B] = fa map f
225}
226
227private trait OptionTApply[F[_]] extends Apply[OptionT[F, *]] with OptionTFunctor[F]{
228  implicit def F: Monad[F]
229
230  override final def ap[A, B](fa: => OptionT[F, A])(f: => OptionT[F, A => B]): OptionT[F, B] = fa ap f
231}
232
233private trait OptionTPoint[F[_]] {
234  implicit def F: Applicative[F]
235
236  def point[A](a: => A): OptionT[F, A] = OptionT[F, A](F.point(some(a)))
237}
238
239private trait OptionTBind[F[_]] extends Bind[OptionT[F, *]] with OptionTFunctor[F]{
240  implicit def F: Monad[F]
241
242  final def bind[A, B](fa: OptionT[F, A])(f: A => OptionT[F, B]): OptionT[F, B] = fa flatMap f
243}
244
245private trait OptionTBindRec[F[_]] extends BindRec[OptionT[F, *]] with OptionTBind[F] {
246  implicit def F: Monad[F]
247  implicit def B: BindRec[F]
248
249  final def tailrecM[A, B](a: A)(f: A => OptionT[F, A \/ B]): OptionT[F, B] =
250    OptionT(
251      B.tailrecM[A, Option[B]](a)(a0 => F.map(f(a0).run) {
252        _.fold(\/.right[A, Option[B]](None: Option[B]))(_.map(Some.apply))
253      })
254    )
255}
256
257private trait OptionTMonad[F[_]] extends Monad[OptionT[F, *]] with OptionTBind[F] with OptionTPoint[F] {
258  implicit def F: Monad[F]
259}
260
261private trait OptionTMonadError[F[_], E] extends MonadError[OptionT[F, *], E] with OptionTMonad[F] {
262  override def F: MonadError[F, E]
263
264  override def raiseError[A](e: E) =
265    OptionT[F, A](F.map(F.raiseError[A](e))(Some(_)))
266
267  override def handleError[A](fa: OptionT[F, A])(f: E => OptionT[F, A]) =
268    OptionT[F, A](F.handleError(fa.run)(f(_).run))
269}
270
271private trait OptionTFoldable[F[_]] extends Foldable.FromFoldr[OptionT[F, *]] {
272  implicit def F: Foldable[F]
273
274  override def foldRight[A, B](fa: OptionT[F, A], z: => B)(f: (A, => B) => B): B = fa.foldRight(z)(f)
275}
276
277private trait OptionTTraverse[F[_]] extends Traverse[OptionT[F, *]] with OptionTFoldable[F] with OptionTFunctor[F]{
278  implicit def F: Traverse[F]
279
280  def traverseImpl[G[_] : Applicative, A, B](fa: OptionT[F, A])(f: A => G[B]): G[OptionT[F, B]] = fa traverse f
281}
282
283private trait OptionTHoist extends Hoist[OptionT] {
284  def liftM[G[_], A](a: G[A])(implicit G: Monad[G]): OptionT[G, A] =
285    OptionT[G, A](G.map[A, Option[A]](a)((a: A) => some(a)))
286
287  def hoist[M[_]: Monad, N[_]](f: M ~> N) =
288    λ[OptionT[M, *] ~> OptionT[N, *]](_ mapT f.apply)
289
290  implicit def apply[G[_] : Monad]: Monad[OptionT[G, *]] = OptionT.optionTMonadPlus[G]
291}
292
293private trait OptionTMonadPlus[F[_]] extends MonadPlus[OptionT[F, *]] with OptionTMonad[F] {
294  implicit def F: Monad[F]
295
296  def empty[A]: OptionT[F, A] = OptionT(F point none[A])
297  def plus[A](a: OptionT[F, A], b: => OptionT[F, A]): OptionT[F, A] = a orElse b
298}
299
300private trait OptionTMonadTell[F[_], W] extends MonadTell[OptionT[F, *], W] with OptionTMonad[F] with OptionTHoist {
301  def MT: MonadTell[F, W]
302
303  implicit def F = MT
304
305  def writer[A](w: W, v: A): OptionT[F, A] =
306    liftM[F, A](MT.writer(w, v))
307}
308
309private trait OptionTMonadListen[F[_], W] extends MonadListen[OptionT[F, *], W] with OptionTMonadTell[F, W] {
310  def MT: MonadListen[F, W]
311
312  def listen[A](ma: OptionT[F, A]): OptionT[F, (A, W)] = {
313    val tmp = MT.bind[(Option[A], W), Option[(A, W)]](MT.listen(ma.run)) {
314      case (None, _) => MT.point(None)
315      case (Some(a), w) => MT.point(Some((a, w)))
316    }
317
318    OptionT.optionT[F].apply[(A, W)](tmp)
319  }
320}