package scalaz.syntax import annotation.tailrec import scalaz.{Applicative, Monoid, NonEmptyList, Kleisli, Reader, \/} import scalaz.Id._ trait IdOps[A] extends Ops[A] { /**Returns `self` if it is non-null, otherwise returns `d`. */ final def ??(d: => A)(implicit ev: Null <:< A): A = if (self == null) d else self /**Applies `self` to the provided function. The Thrush combinator. */ final def |>[B](f: A => B): B = f(self) /**Applies `self` to the provide function for its side effect, and returns `self`. The Kestrel combinator. * Mostly for use with dodgy libraries that give you values that need additional initialization or * mutation before they're valid to use. */ final def unsafeTap(f: A => Any): A = { f(self); self } /** Alias for `unsafeTap`. */ final def <|(f: A => Any): A = unsafeTap(f) final def squared: (A, A) = (self, self) def left[B]: (A \/ B) = \/.left(self) def right[B]: (B \/ A) = \/.right(self) final def wrapNel: NonEmptyList[A] = NonEmptyList(self) /** * @return the result of pf(value) if defined, otherwise the the Zero element of type B. */ def matchOrZero[B: Monoid](pf: PartialFunction[A, B]): B = pf.lift(self) match { case None => Monoid[B].zero case Some(x) => x } /** Repeatedly apply `f`, seeded with `self`, checking after each iteration whether the predicate `p` holds. */ final def doWhile(f: A => A, p: A => Boolean): A = { @tailrec def loop(value: A): A = { val x = f(value) if (p(x)) loop(x) else x } loop(self) } /** Repeatedly apply `f`, seeded with `self`, checking before each iteration whether the predicate `p` holds. */ final def whileDo(f: A => A, p: A => Boolean): A = { @tailrec def loop(value: A): A = { if (p(value)) loop(f(value)) else value } loop(self) } /** * If the provided partial function is defined for `self` run this, * otherwise lift `self` into `F` with the provided [[scalaz.Applicative]]. */ def visit[F[_] : Applicative](p: PartialFunction[A, F[A]]): F[A] = if (p isDefinedAt self) p(self) else Applicative[F].point(self) } trait ToIdOps { implicit def ToIdOps[A](a: A): IdOps[A] = new IdOps[A] { def self: A = a } }