/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

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