/core/src/main/scala/scalaz/OptionT.scala
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}