package scalaz sealed trait NonEmptyList[+A] { val head: A val tail: List[A] import Scalaz._ def <::[B >: A](b: B): NonEmptyList[B] = nel(b, head :: tail) import collection.mutable.ListBuffer def <:::[B >: A](bs: List[B]): NonEmptyList[B] = { val b = new ListBuffer[B] b ++= bs b += head b ++= tail val bb = b.toList nel(bb.head, bb.tail) } def :::>[B >: A](bs: List[B]): NonEmptyList[B] = nel(head, tail ::: bs) def map[B](f: A => B): NonEmptyList[B] = nel(f(head), tail.map(f)) def flatMap[B](f: A => NonEmptyList[B]): NonEmptyList[B] = { val b = new ListBuffer[B] val p = f(head) b += p.head b ++= p.tail tail.foreach(a => { val p = f(a) b += p.head b ++= p.tail }) val bb = b.toList nel(bb.head, bb.tail) } lazy val list: List[A] = head :: tail lazy val stream: Stream[A] = head #:: tail.toStream def toZipper: Zipper[A] = zipper(Stream.Empty, head, tail.toStream) def zipperEnd: Zipper[A] = { import Stream._ tail reverse match { case Nil => zipper(empty, head, empty) case t :: ts => zipper(ts.toStream :+ head, t, empty) } } def tails: NonEmptyList[NonEmptyList[A]] = nel(this, tail.toNel match { case None => Nil case Some(t) => t.tails.list }) def reverse: NonEmptyList[A] = (list.reverse: @unchecked) match { case x :: xs => nel(x, xs) } override def toString: String = "NonEmpty" + (head :: tail) } trait NonEmptyLists { def nel[A](h: A, t: A*): NonEmptyList[A] = new NonEmptyList[A] { val head = h val tail = t.toList } def nel[A](h: A, t: List[A]): NonEmptyList[A] = new NonEmptyList[A] { val head = h val tail = t.toList } } object NonEmptyList extends NonEmptyLists { def apply[A](h: A, t: A*): NonEmptyList[A] = nel(h, t: _*) }