package scalaz package syntax package std import scalaz.std.{option => o} import scalaz.Tags.{Last, First} trait OptionOps[A] extends Ops[Option[A]] { final def cata[X](some: A => X, none: => X): X = o.cata(self)(some, none) final def fold[X](some: A => X, none: => X): X = cata(some, none) sealed trait Fold[X] { def none(s: => X): X } /** * Returns the provided function `s` applied to item contained in the Option if it is defined, * otherwise, the provided value `n`. * <p/> * This is a syntactic alternative to [[scalaz.syntax.std.OptionOps#cata]] * <p/> * Example: * {{{ * o.some(_ * 2).none(0) * }}} */ final def some[X](s: A => X): Fold[X] = new Fold[X] { def none(n: => X): X = cata(s, n) } sealed trait Conditional[X] { def |(n: => X): X } /** * Ternary operator. Note that the arguments s and n are call-by-name. * <p/> * Example * {{{ * option ? "defined" | "undefined" * }}} */ final def ?[X](s: => X): Conditional[X] = new Conditional[X] { def |(n: => X): X = self match { case None => n case Some(_) => s } } /** * Executes the provided side effect if the Option if it is undefined. */ final def ifNone(n: => Unit): Unit = if (self.isEmpty) n /** * Returns the item contained in the Option if it is defined, otherwise, raises an error with the provided message. */ final def err(message: => String): A = self.getOrElse(sys.error(message)) /** * Returns the item contained in the Option if it is defined, otherwise, the provided argument. */ final def |(a: => A): A = self getOrElse a /** * Returns the item contained in the Option if it is defined, otherwise, the zero element for the type A * <p/> * For example: * {{{ * val o: Option = None * val a: List[String] = ~o * }}} */ final def unary_~(implicit z: Monoid[A]): A = self getOrElse z.zero final def orZero(implicit z: Monoid[A]): A = self getOrElse z.zero final def toSuccess[E](e: => E): Validation[E, A] = o.toSuccess(self)(e) final def toFailure[B](b: => B): Validation[A, B] = o.toFailure(self)(b) final def toRightDisjunction[E](e: => E): E \/ A = o.toRight(self)(e) final def toLeftDisjunction[B](b: => B): A \/ B = o.toLeft(self)(b) final def \/>[E](e: => E): E \/ A = o.toRight(self)(e) final def <\/[B](b: => B): A \/ B = o.toLeft(self)(b) final def first: Option[A] @@ First = Tag(self) final def last: Option[A] @@ Last = Tag(self) final def orEmpty[M[_] : Applicative : PlusEmpty]: M[A] = o.orEmpty[A, M](self) final def foldLift[F[_] : Applicative, B](b: => B, k: F[A] => B): B = o.foldLift(self)(b, k) final def foldLiftOpt[B](b: => B, k: Option[A] => B): B = o.foldLiftOpt[A, B](self)(b, k) } trait ToOptionOps { implicit def ToOptionOpsFromOption[A](a: Option[A]): OptionOps[A] = new OptionOps[A] { val self = a } }