All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scalaz.OneAnd.scala Maven / Gradle / Ivy

The newest version!
package scalaz

import scalaz.Isomorphism.{<~>, IsoFunctorTemplate}
import scalaz.std.option.{optionMonoid, none, some}
import scalaz.Ordering.orderingInstance

/** A generalization of `NonEmptyList` to non-`List` things.  For
  * example, `OneAnd[Vector, A]` is a non-empty `Vector` of `A`.
  *
  * Only `head` and `tail` are provided as direct methods, because
  * there's little you can do with a `OneAnd` without knowing a bit
  * about `F`.  So useful functions are provided in the form of
  * typeclass instances on `OneAnd`'s companion; in combination with
  * syntax extensions provided by `scalaz.syntax`, `OneAnd` has a
  * large possible set of methods available by importing.  For
  * example, `Applicative` on this requires `ApplicativePlus[F]`, and
  * `Traverse1` on this requires `Traverse[F]`.  See the companion
  * documentation for a complete list of instances.
  *
  * Additionally, unlike `λ[α => (α, F[α])]`, the behavior of typeclass
  * operations on `OneAnd` should be preserved across the natural
  * transformation to [[scalaz.NonEmptyList]] where one exists.  That
  * is it should "be like" a nonempty structure.  For example,
  * `ap`-ing two `OneAnd[Vector, *]`s or `NonEmptyList`s of lengths
  * *a* and *b* yields a sequence of same type of length *a*×*b*, but
  * two `λ[α => (α, Vector[α])]`s of length *c* and *d* `ap` to one of
  * length 1+(*c*–1)×(*d*–1).  For another example, `point` of the
  * former two yield a one-element sequence, but `point` of the latter
  * yields a two-element sequence.
  *
  * @since 7.0.3
  */
final class OneAnd[F[_], A] private (
  private val hd: Name[A],
  private val tl: Name[F[A]]
) {
  def head: A = hd.value
  def tail: F[A] = tl.value

  // OneAnd used to be a case class...
  override def toString: String = s"OneAnd($head,$tail)"
  override def hashCode: Int = head.hashCode + 13*tail.hashCode
  override def equals(that: Any): Boolean = that match {
    case that: OneAnd[_, _] => (this eq that) || ((head == that.head) && (tail == that.tail))
    case _ => false
  }
}

private sealed trait OneAndFunctor[F[_]] extends Functor[OneAnd[F, *]] {
  def F: Functor[F]

  override def map[A, B](fa: OneAnd[F, A])(f: A => B): OneAnd[F, B] =
    OneAnd(f(fa.head), F.map(fa.tail)(f))
}

private sealed trait OneAndApply[F[_]] extends Apply[OneAnd[F, *]] with OneAndFunctor[F] {
  def F: Applicative[F]
  def G: Plus[F]

  override def ap[A, B](fa: => OneAnd[F, A])(f: => OneAnd[F, A => B]): OneAnd[F, B] = {
    val OneAnd(hf, tf) = f
    val OneAnd(ha, ta) = fa
    OneAnd(hf(ha), G.plus(F.map(ta)(hf),
                          F.ap(G.plus(F.point(ha), ta))(tf)))
  }
}

private sealed trait OneAndAlign[F[_]] extends Align[OneAnd[F, *]] with OneAndFunctor[F] {
  def F: Align[F]

  override def alignWith[A, B, C](f: A \&/ B => C) = {
    case (OneAnd(ha, ta), OneAnd(hb, tb)) =>
      OneAnd(f(\&/.Both(ha, hb)), F.alignWith(f)(ta, tb))
  }
}

private sealed trait OneAndApplicative[F[_]] extends Applicative[OneAnd[F, *]] with OneAndApply[F] {
  def F: Applicative[F]
  def G: PlusEmpty[F]

  def point[A](a: => A): OneAnd[F, A] = OneAnd(a, G.empty)
}

private sealed trait OneAndAlt[F[_]] extends Alt[OneAnd[F, *]] with OneAndApplicative[F] {
  def F: Alt[F]
  def G: PlusEmpty[F]

  def alt[A](a: => OneAnd[F, A], b: => OneAnd[F, A]): OneAnd[F, A] =
    OneAnd(a.head, F.alt(F.alt(a.tail, F.point(b.head)), b.tail))
}

private sealed trait OneAndBind[F[_]] extends Bind[OneAnd[F, *]] with OneAndApply[F] {
  def F: Monad[F]
  def G: Plus[F]

  def bind[A, B](fa: OneAnd[F, A])(f: A => OneAnd[F, B]): OneAnd[F, B] = OneAnd(
    f(fa.head).head,
    G.plus(
      f(fa.head).tail,
      F.bind(fa.tail){ a =>
        val x = f(a)
        G.plus(F.point(x.head), x.tail)
      }
    )
  )
}

private sealed trait OneAndPlus[F[_]] extends Plus[OneAnd[F, *]] {
  def F: Applicative[F]
  def G: Plus[F]

  def plus[A](a: OneAnd[F, A], b: => OneAnd[F, A]): OneAnd[F, A] =
    OneAnd(a.head, G.plus(G.plus(a.tail, F.point(b.head)), b.tail))
}

private sealed trait OneAndMonad[F[_]] extends Monad[OneAnd[F, *]] with OneAndBind[F] with OneAndApplicative[F] {
  def F: MonadPlus[F]
  def G: MonadPlus[F] = F
}

private sealed trait OneAndFoldable[F[_]] extends Foldable1[OneAnd[F, *]] {
  def F: Foldable[F]

  override def findLeft[A](fa: OneAnd[F, A])(f: A => Boolean) =
    if(f(fa.head)) Some(fa.head) else F.findLeft(fa.tail)(f)

  override def findRight[A](fa: OneAnd[F, A])(f: A => Boolean) =
    F.findRight(fa.tail)(f) match {
      case a @ Some(_) =>
        a
      case None =>
        if(f(fa.head)) Some(fa.head) else None
    }

  override def foldMap1[A, B: Semigroup](fa: OneAnd[F, A])(f: A => B) =
    foldMap(fa)(a => some(f(a))) getOrElse f(fa.head)

  override def foldMapRight1[A, B](fa: OneAnd[F, A])(z: A => B)(f: (A, => B) => B) =
    (F.foldRight(fa.tail, none[B])((a, ob) => ob map (f(a, _)) orElse some(z(a)))
       map (f(fa.head, _)) getOrElse z(fa.head))

  override def foldMapLeft1[A, B](fa: OneAnd[F, A])(z: A => B)(f: (B, A) => B) =
    F.foldLeft(fa.tail, z(fa.head))(f)

  override def foldMap[A, B](fa: OneAnd[F, A])(f: A => B)(implicit M: Monoid[B]) =
    M.append(f(fa.head), F.foldMap(fa.tail)(f))

  override def foldRight[A, B](fa: OneAnd[F, A], z: => B)(f: (A, => B) => B) =
    f(fa.head, F.foldRight(fa.tail, z)(f))

  override def foldLeft[A, B](fa: OneAnd[F, A], z: B)(f: (B, A) => B) =
    F.foldLeft(fa.tail, f(z, fa.head))(f)

  override def traverseS_[S,A,B](fa: OneAnd[F, A])(f: A => State[S,B]) =
    State{(s: S) => F.traverseS_(fa.tail)(f)(f(fa.head)(s)._1)}

  override def length[A](fa: OneAnd[F, A]) = 1 + F.length(fa.tail)

  override def index[A](fa: OneAnd[F, A], i: Int) =
    if (i == 0) Some(fa.head) else F.index(fa.tail, i - 1)

  override def toVector[A](fa: OneAnd[F, A]) =
    fa.head +: F.toVector(fa.tail)

  override def toList[A](fa: OneAnd[F, A]) =
    fa.head :: F.toList(fa.tail)

  override def toIList[A](fa: OneAnd[F, A]) =
    fa.head :: F.toIList(fa.tail)

  override def toSet[A](fa: OneAnd[F, A]) =
    F.toSet(fa.tail) + fa.head

  override def toLazyList[A](fa: OneAnd[F, A]) =
    fa.head #:: F.toLazyList(fa.tail)

  override def toEphemeralStream[A](fa: OneAnd[F, A]) =
    EphemeralStream.cons(fa.head, F.toEphemeralStream(fa.tail))

  override def all[A](fa: OneAnd[F, A])(f: A => Boolean) =
    f(fa.head) && F.all(fa.tail)(f)

  override def any[A](fa: OneAnd[F, A])(f: A => Boolean) =
    f(fa.head) || F.any(fa.tail)(f)
}

private sealed trait OneAndFoldable1[F[_]] extends OneAndFoldable[F] {
  def F: Foldable1[F]

  override def foldMap1[A, B](fa: OneAnd[F, A])(f: A => B)(implicit S: Semigroup[B]) =
    S.append(f(fa.head), F.foldMap1(fa.tail)(f))

  override def foldMapRight1[A, B](fa: OneAnd[F, A])(z: A => B)(f: (A, => B) => B) =
    f(fa.head, F.foldMapRight1(fa.tail)(z)(f))
}

private sealed trait OneAndTraverse[F[_]] extends Traverse1[OneAnd[F, *]] with OneAndFunctor[F] with OneAndFoldable[F] {
  def F: Traverse[F]

  def traverse1Impl[G[_],A,B](fa: OneAnd[F, A])(f: A => G[B])(implicit G: Apply[G]) =
    G.applyApplicative.traverse(fa.tail)(f andThen \/.left[G[B], B])(F)
     .fold(ftl => G.apply2(f(fa.head), ftl)(OneAnd.apply),
           tl => G.map(f(fa.head))(OneAnd(_, tl)))

  override def traverseImpl[G[_],A,B](fa: OneAnd[F, A])(f: A => G[B])(implicit G: Applicative[G]) =
    G.apply2(f(fa.head), F.traverseImpl(fa.tail)(f)(using G))(OneAnd.apply)

  override def traverseS[S,A,B](fa: OneAnd[F, A])(f: A => State[S,B]) =
    State{(s: S) =>
      val (s2, b) = f(fa.head)(s)
      val (s3, bs) = F.traverseS(fa.tail)(f)(s2)
      (s3, OneAnd(b, bs))
    }
}

private sealed trait OneAndTraverse1[F[_]] extends OneAndTraverse[F] with OneAndFoldable1[F] {
  def F: Traverse1[F]

  override def traverse1Impl[G[_],A,B](fa: OneAnd[F, A])(f: A => G[B])(implicit G: Apply[G]) =
    G.apply2(f(fa.head), F.traverse1Impl(fa.tail)(f)(using G))(OneAnd.apply)
}

sealed abstract class OneAndInstances5 {
  implicit def oneAndFunctor[F[_]: Functor]: Functor[OneAnd[F, *]] =
    new OneAndFunctor[F] {
      def F = implicitly
    }
}

sealed abstract class OneAndInstances4 extends OneAndInstances5 {
  implicit def oneAndApply[F[_]: Applicative: Plus]: Apply[OneAnd[F, *]] =
    new OneAndApply[F] {
      def F = implicitly
      def G = implicitly
    }

  implicit def oneAndAlign[F[_]: Align]: Align[OneAnd[F, *]] =
    new OneAndAlign[F] {
      def F = implicitly
    }
}

sealed abstract class OneAndInstances3 extends OneAndInstances4 {
  implicit def oneAndApplicative[F[_]: ApplicativePlus]: Applicative[OneAnd[F, *]] =
    new OneAndApplicative[F] {
      def F = implicitly
      def G = implicitly
    }
}

sealed abstract class OneAndInstances2 extends OneAndInstances3 {
  implicit def oneAndBind[F[_]: Monad: Plus]: Bind[OneAnd[F, *]] =
    new OneAndBind[F] {
      def F = implicitly
      def G = implicitly
    }

  implicit def oneAndAlt[F[_]: Alt: PlusEmpty]: Alt[OneAnd[F, *]] =
    new OneAndAlt[F] {
      def F = implicitly
      def G = implicitly
    }
}

sealed abstract class OneAndInstances1 extends OneAndInstances2 {
  implicit def oneAndMonad[F[_]: MonadPlus]: Monad[OneAnd[F, *]] =
    new OneAndMonad[F] {
      def F = implicitly
    }

  implicit def oneAndFoldable[F[_]: Foldable]: Foldable1[OneAnd[F, *]] =
    new OneAndFoldable[F] {
      def F = implicitly
    }
}

private sealed trait OneAndEqual[F[_], A] extends Equal[OneAnd[F, A]] {
  def OA: Equal[A]
  def OFA: Equal[F[A]]

  override def equal(a1: OneAnd[F, A], a2: OneAnd[F, A]) =
    OA.equal(a1.head, a2.head) && OFA.equal(a1.tail, a2.tail)

  override def equalIsNatural = OA.equalIsNatural && OFA.equalIsNatural
}

sealed abstract class OneAndInstances0 extends OneAndInstances1 {
  /** If you have `Foldable1[F]`, `foldMap1` and `foldRight1` are
    * nonstrict and significantly more efficient.
    */
  implicit def oneAndFoldable1[F[_]: Foldable1]: Foldable1[OneAnd[F, *]] =
    new OneAndFoldable1[F] {
      def F = implicitly
    }

  implicit def oneAndEqual[F[_], A](implicit A: Equal[A], FA: Equal[F[A]]): Equal[OneAnd[F, A]] =
    new OneAndEqual[F, A] {
      def OA = A
      def OFA = FA
    }

  implicit def oneAndTraverse[F[_]: Traverse]: Traverse1[OneAnd[F, *]] =
    new OneAndTraverse[F] {
      def F = implicitly
    }
}

sealed abstract class OneAndInstances extends OneAndInstances0 {
  implicit def oneAndPlus[F[_]: Applicative: Plus]: Plus[OneAnd[F, *]] =
    new OneAndPlus[F] {
      def F = implicitly
      def G = implicitly
    }

  implicit def oneAndTraverse1[F[_]: Traverse1]: Traverse1[OneAnd[F, *]] =
    new OneAndTraverse1[F] {
      def F = implicitly
    }

  implicit def oneAndShow[F[_], A](implicit A: Show[A], FA: Show[F[A]]): Show[OneAnd[F, A]] = {
    import scalaz.syntax.show._
    Show.show { f => cord"OneAnd(${f.head},${f.tail})" }
  }

  implicit def oneAndOrder[F[_], A](implicit A: Order[A], FA: Order[F[A]]): Order[OneAnd[F, A]] =
    new Order[OneAnd[F, A]] with OneAndEqual[F, A] {
      def OA: Order[A] = A
      def OFA: Order[F[A]] = FA
      def order(a1: OneAnd[F, A], a2: OneAnd[F, A]) =
        Monoid[Ordering].append(A.order(a1.head, a2.head),
                                FA.order(a1.tail, a2.tail))
    }

  implicit def oneAndSemigroup[F[_]: Applicative: Plus, A]: Semigroup[OneAnd[F, A]] =
    oneAndPlus[F].semigroup

  implicit def oneAndZip[F[_]: Zip]: Zip[OneAnd[F, *]] =
    new Zip[OneAnd[F, *]] {
      def zip[A, B](a: => OneAnd[F, A], b: => OneAnd[F, B]) = {
        val a0 = a
        val b0 = b
        OneAnd((a0.head, b0.head), Zip[F].zip(a0.tail, b0.tail))
      }
    }

  implicit def oneAndUnzip[F[_]: Unzip]: Unzip[OneAnd[F, *]] =
    new Unzip[OneAnd[F, *]] {
      def unzip[A, B](a: OneAnd[F, (A, B)]) = {
        val (fa, fb) = Unzip[F].unzip(a.tail)
        val (aa, ab) = a.head
        (OneAnd(aa, fa), OneAnd(ab, fb))
      }
    }
}

object OneAnd extends OneAndInstances {
  def apply[F[_], A](hd: A, tl: F[A]): OneAnd[F, A] = Strict(hd, tl)
  def unapply[F[_], A](oa: OneAnd[F, A]): Some[(A, F[A])] = Some((oa.head, oa.tail))

  object ByName {
    def apply[F[_], A](hd: =>A, tl: => F[A]): OneAnd[F, A] = new OneAnd(Name(hd), Name(tl))
  }
  object Lazy {
    def apply[F[_], A](hd: =>A, tl: => F[A]): OneAnd[F, A] = new OneAnd(Need(hd), Need(tl))
  }
  object Strict {
    def apply[F[_], A](hd: A, tl: F[A]): OneAnd[F, A] = new OneAnd(Value(hd), Value(tl))
  }

  val oneAndNelIso: NonEmptyList <~> OneAnd[IList, *] =
    new IsoFunctorTemplate[NonEmptyList, OneAnd[IList, *]] {
      def to_[A](fa: NonEmptyList[A]) = OneAnd(fa.head, fa.tail)
      def from_[A](ga: OneAnd[IList, A]) = NonEmptyList.nel(ga.head, ga.tail)
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy