/core/src/main/scala/scalaz/NonEmptyList.scala

http://github.com/scalaz/scalaz · Scala · 265 lines · 188 code · 67 blank · 10 comment · 5 complexity · 3239fa4c24700d1fe560fb9938feb36d MD5 · raw file

  1. package scalaz
  2. /** A singly-linked list that is guaranteed to be non-empty. */
  3. final class NonEmptyList[A] private[scalaz](val head: A, val tail: IList[A]) {
  4. import NonEmptyList._
  5. import Zipper._
  6. import scalaz.Liskov._
  7. def <::(b: A): NonEmptyList[A] = nel(b, head :: tail)
  8. def <:::(bs: IList[A]): NonEmptyList[A] = bs match {
  9. case INil() => this
  10. case ICons(b, bs) => nel(b, bs ::: list)
  11. }
  12. def :::>(bs: IList[A]): NonEmptyList[A] = nel(head, tail ::: bs)
  13. /** Append one nonempty list to another. */
  14. def append(f2: NonEmptyList[A]): NonEmptyList[A] = list <::: f2
  15. def map[B](f: A => B): NonEmptyList[B] = nel(f(head), tail.map(f))
  16. /** @since 7.0.3 */
  17. def foreach(f: A => Unit): Unit = {
  18. f(head)
  19. tail.foldLeft(()){(_, a) =>
  20. f(a)
  21. ()
  22. }
  23. }
  24. def flatMap[B](f: A => NonEmptyList[B]): NonEmptyList[B] = {
  25. val rev = reverse
  26. rev.tail.foldLeft(f(rev.head))((nel, b) => f(b) append nel)
  27. }
  28. def distinct(implicit A: Order[A]): NonEmptyList[A] =
  29. (list.distinct: @unchecked) match {
  30. case ICons(x, xs) => nel(x, xs)
  31. }
  32. def traverse1[F[_], B](f: A => F[B])(implicit F: Apply[F]): F[NonEmptyList[B]] = {
  33. tail match {
  34. case INil() => F.map(f(head))(nel(_, IList.empty))
  35. case ICons(b, bs) => F.apply2(f(head), OneAnd.oneAndTraverse[IList].traverse1(OneAnd(b, bs))(f)) {
  36. case (h, t) => nel(h, t.head :: t.tail)
  37. }
  38. }
  39. }
  40. def list: IList[A] = head :: tail
  41. def stream: Stream[A] = head #:: tail.toStream
  42. def toZipper: Zipper[A] = zipper(Stream.Empty, head, tail.toStream)
  43. def zipperEnd: Zipper[A] = {
  44. import Stream._
  45. tail.reverse match {
  46. case INil() => zipper(empty, head, empty)
  47. case ICons(t, ts) => zipper(ts.toStream :+ head, t, empty)
  48. }
  49. }
  50. /** @since 7.0.2 */
  51. def init: IList[A] = tail.initMaybe.cata(il => head :: il, IList.empty[A])
  52. def inits: NonEmptyList[NonEmptyList[A]] =
  53. reverse.tails.map(_.reverse)
  54. /** @since 7.0.2 */
  55. def last: A = tail.lastOption.getOrElse(head)
  56. def tails: NonEmptyList[NonEmptyList[A]] = {
  57. @annotation.tailrec
  58. def tails0(as: NonEmptyList[A], accum: IList[NonEmptyList[A]]): NonEmptyList[NonEmptyList[A]] =
  59. as.tail match {
  60. case INil() => nel(as, accum).reverse
  61. case ICons(h, t) => tails0(nel(h, t), as :: accum)
  62. }
  63. tails0(this, IList.empty)
  64. }
  65. def reverse: NonEmptyList[A] = (list.reverse: @unchecked) match {
  66. case ICons(x, xs) => nel(x, xs)
  67. }
  68. /** @since 7.0.2 */
  69. def sortBy[B](f: A => B)(implicit o: Order[B]): NonEmptyList[A] = (list.sortBy(f): @unchecked) match {
  70. case ICons(x, xs) => nel(x, xs)
  71. }
  72. /** @since 7.0.2 */
  73. def sortWith(lt: (A, A) => Boolean): NonEmptyList[A] =
  74. (list.toList.sortWith(lt): @unchecked) match {
  75. case x :: xs => nel(x, IList.fromList(xs))
  76. }
  77. /** @since 7.0.2 */
  78. def sorted(implicit o: Order[A]): NonEmptyList[A] = (list.sorted(o): @unchecked) match {
  79. case ICons(x, xs) => nel(x, xs)
  80. }
  81. def size: Int = 1 + tail.length
  82. def zip[B](b: => NonEmptyList[B]): NonEmptyList[(A, B)] = {
  83. val _b = b
  84. nel((head, _b.head), tail zip _b.tail)
  85. }
  86. def unzip[X, Y](implicit ev: A <~< (X, Y)): (NonEmptyList[X], NonEmptyList[Y]) = {
  87. val (a, b) = ev(head)
  88. val (aa, bb) = tail.unzip: (IList[X], IList[Y])
  89. (nel(a, aa), nel(b, bb))
  90. }
  91. def zipWithIndex: NonEmptyList[(A, Int)] = {
  92. @annotation.tailrec
  93. def loop(as: IList[A], i: Int, acc: IList[(A, Int)]): IList[(A, Int)] =
  94. as match {
  95. case ICons(x, y) => loop(y, i + 1, (x, i) :: acc)
  96. case _ => acc.reverse
  97. }
  98. new NonEmptyList((head, 0), loop(tail, 1, IList.empty))
  99. }
  100. override def toString: String = "NonEmpty" + (head :: tail)
  101. override def equals(any: Any): Boolean =
  102. any match {
  103. case that: NonEmptyList[_] => this.list == that.list
  104. case _ => false
  105. }
  106. override def hashCode: Int =
  107. list.hashCode
  108. }
  109. object NonEmptyList extends NonEmptyListInstances {
  110. // optimised versions of apply(A*)
  111. @inline final def apply[A](a: A): NonEmptyList[A] = nel(a, IList.empty)
  112. @inline final def apply[A](a: A, b: A): NonEmptyList[A] = nel(a, IList(b))
  113. @inline final def apply[A](a: A, b: A, c: A): NonEmptyList[A] = nel(a, IList(b, c))
  114. @inline final def apply[A](a: A, b: A, c: A, d: A): NonEmptyList[A] = nel(a, IList(b, c, d))
  115. @inline final def apply[A](a: A, b: A, c: A, d: A, e: A): NonEmptyList[A] = nel(a, IList(b, c, d, e))
  116. @inline final def apply[A](a: A, b: A, c: A, d: A, e: A, f: A): NonEmptyList[A] = nel(a, IList(b, c, d, e, f))
  117. @inline final def apply[A](a: A, b: A, c: A, d: A, e: A, f: A, as: A*): NonEmptyList[A] = a <:: b <:: c <:: d <:: e <:: fromSeq(f, as)
  118. def fromSeq[A](h: A, t: Seq[A]): NonEmptyList[A] =
  119. nel(h, IList.fromSeq(t))
  120. def unapply[A](v: NonEmptyList[A]): Option[(A, IList[A])] =
  121. Some((v.head, v.tail))
  122. def nel[A](h: A, t: IList[A]): NonEmptyList[A] =
  123. new NonEmptyList(h, t)
  124. def lift[A, B](f: NonEmptyList[A] => B): IList[A] => Option[B] = {
  125. case INil() => None
  126. case ICons(h, t) => Some(f(NonEmptyList.nel(h, t)))
  127. }
  128. }
  129. sealed abstract class NonEmptyListInstances0 {
  130. implicit def nonEmptyListEqual[A: Equal]: Equal[NonEmptyList[A]] = Equal.equalBy[NonEmptyList[A], IList[A]](_.list)(IList.equal[A])
  131. }
  132. sealed abstract class NonEmptyListInstances extends NonEmptyListInstances0 {
  133. implicit val nonEmptyList: Traverse1[NonEmptyList] with Monad[NonEmptyList] with Alt[NonEmptyList] with BindRec[NonEmptyList] with Plus[NonEmptyList] with Comonad[NonEmptyList] with Zip[NonEmptyList] with Unzip[NonEmptyList] with Align[NonEmptyList] =
  134. new Traverse1[NonEmptyList] with Monad[NonEmptyList] with Alt[NonEmptyList] with BindRec[NonEmptyList] with Plus[NonEmptyList] with Comonad[NonEmptyList] with Zip[NonEmptyList] with Unzip[NonEmptyList] with Align[NonEmptyList] {
  135. override def findLeft[A](fa: NonEmptyList[A])(f: A => Boolean) =
  136. if(f(fa.head)) Some(fa.head) else fa.tail.find(f).toOption
  137. override def foldMap[A, B](fa: NonEmptyList[A])(f: A => B)(implicit M: Monoid[B]) =
  138. Foldable[IList].foldMap(fa.list)(f)(M)
  139. override def traverse1[F[_], A, B](fa: NonEmptyList[A])(f: A => F[B])(implicit F: Apply[F]) = {
  140. val revOpt: Maybe[F[NonEmptyList[B]]] =
  141. F.unfoldrOpt[IList[A], B, NonEmptyList[B]](fa.list)(_ match {
  142. case ICons(a, as) => Maybe.just((f(a), as))
  143. case INil() => Maybe.empty
  144. })(Reducer.ReverseNonEmptyListReducer[B])
  145. val rev: F[NonEmptyList[B]] = revOpt getOrElse sys.error("Head cannot be empty")
  146. F.map(rev)(_.reverse)
  147. }
  148. def traverse1Impl[G[_] : Apply, A, B](fa: NonEmptyList[A])(f: A => G[B]): G[NonEmptyList[B]] =
  149. fa traverse1 f
  150. override def foldMapRight1[A, B](fa: NonEmptyList[A])(z: A => B)(f: (A, => B) => B): B = {
  151. val reversed = fa.reverse
  152. reversed.tail.foldLeft(z(reversed.head))((x, y) => f(y, x))
  153. }
  154. override def foldMapLeft1[A, B](fa: NonEmptyList[A])(z: A => B)(f: (B, A) => B): B =
  155. fa.tail.foldLeft(z(fa.head))(f)
  156. override def foldMap1[A, B](fa: NonEmptyList[A])(f: A => B)(implicit F: Semigroup[B]): B = {
  157. fa.tail.foldLeft(f(fa.head))((x, y) => F.append(x, f(y)))
  158. }
  159. override def psumMap1[A, B, G[_]](fa: NonEmptyList[A])(f: A => G[B])(implicit G: Plus[G]): G[B] =
  160. fa.tail match {
  161. case INil() => f(fa.head)
  162. case ICons(snd, rest) => G.plus(f(fa.head), psumMap1(NonEmptyList.nel(snd, rest))(f)(G))
  163. }
  164. // would otherwise use traverse1Impl
  165. override def foldLeft[A, B](fa: NonEmptyList[A], z: B)(f: (B, A) => B): B =
  166. fa.tail.foldLeft(f(z, fa.head))(f)
  167. def bind[A, B](fa: NonEmptyList[A])(f: A => NonEmptyList[B]): NonEmptyList[B] = fa flatMap f
  168. def point[A](a: => A): NonEmptyList[A] = NonEmptyList(a)
  169. def plus[A](a: NonEmptyList[A], b: => NonEmptyList[A]): NonEmptyList[A] = a.list <::: b
  170. def alt[A](a: => NonEmptyList[A], b: => NonEmptyList[A]): NonEmptyList[A] = plus(a, b)
  171. def copoint[A](p: NonEmptyList[A]): A = p.head
  172. def cobind[A, B](fa: NonEmptyList[A])(f: NonEmptyList[A] => B): NonEmptyList[B] = map(cojoin(fa))(f)
  173. override def cojoin[A](a: NonEmptyList[A]): NonEmptyList[NonEmptyList[A]] = a.tails
  174. def zip[A, B](a: => NonEmptyList[A], b: => NonEmptyList[B]) = a zip b
  175. def unzip[A, B](a: NonEmptyList[(A, B)]) = a.unzip
  176. def alignWith[A, B, C](f: A \&/ B => C) = (a, b) => {
  177. NonEmptyList.nel(f(\&/.Both(a.head, b.head)), Align[IList].alignWith(f)(a.tail, b.tail))
  178. }
  179. override def length[A](a: NonEmptyList[A]): Int = a.size
  180. override def toNel[A](fa: NonEmptyList[A]) = fa
  181. override def toIList[A](fa: NonEmptyList[A]) = fa.list
  182. override def all[A](fa: NonEmptyList[A])(f: A => Boolean) =
  183. f(fa.head) && Foldable[IList].all(fa.tail)(f)
  184. override def any[A](fa: NonEmptyList[A])(f: A => Boolean) =
  185. f(fa.head) || Foldable[IList].any(fa.tail)(f)
  186. def tailrecM[A, B](a: A)(f: A => NonEmptyList[A \/ B]): NonEmptyList[B] =
  187. (BindRec[IList].tailrecM[A, B](a)(a => f(a).list): @unchecked) match {
  188. case ICons(h, t) => NonEmptyList.nel(h, t)
  189. }
  190. }
  191. implicit def nonEmptyListSemigroup[A]: Semigroup[NonEmptyList[A]] = new Semigroup[NonEmptyList[A]] {
  192. def append(f1: NonEmptyList[A], f2: => NonEmptyList[A]) = f1 append f2
  193. }
  194. implicit def nonEmptyListShow[A: Show]: Show[NonEmptyList[A]] =
  195. Contravariant[Show].contramap(IList.show[A])(_.list)
  196. implicit def nonEmptyListOrder[A: Order]: Order[NonEmptyList[A]] =
  197. Order.orderBy[NonEmptyList[A], IList[A]](_.list)(IList.order[A])
  198. }