Last active
December 10, 2018 00:06
-
-
Save joshlemer/e403df6846568f687df2d73af809bebd to your computer and use it in GitHub Desktop.
Nel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.collection.mutable | |
import scala.collection.immutable.{AbstractSeq, LinearSeq, LinearSeqOps, StrictOptimizedSeqOps} | |
final class Nel[+A](override val head: A, override val tail: List[A]) | |
extends AbstractSeq[A] | |
with LinearSeq[A] | |
with LinearSeqOps[A, LinearSeq, LinearSeq[A]] | |
with StrictOptimizedSeqOps[A, LinearSeq, LinearSeq[A]] { | |
override def toList: List[A] = head :: tail | |
private[this] def fromList[A0 >: A](list: List[A0]): Nel[A0] = new Nel(list.head, list.tail) | |
override def distinctBy[B](f: A => B): Nel[A] = fromList(toList.distinctBy(f)) | |
override def updated[B >: A](index: Int, elem: B): Nel[B] = | |
if (index == 0) new Nel(elem, tail) | |
else new Nel(head, tail.updated(index - 1, elem)) | |
override def prepended[B >: A](elem: B): Nel[B] = new Nel(elem, head :: tail) | |
override def appended[B >: A](elem: B): Nel[B] = new Nel(head, tail.appended(elem)) | |
override def appendedAll[B >: A](suffix: IterableOnce[B]): Nel[B] = new Nel(head, tail.appendedAll(suffix)) | |
override def prependedAll[B >: A](prefix: IterableOnce[B]): Nel[B] = fromList(toList.prependedAll(prefix)) | |
override def padTo[B >: A](len: Int, elem: B): Nel[B] = fromList(toList.padTo(len, elem)) | |
override def unzip[A1, A2](implicit asPair: A => (A1, A2)): (Nel[A1], Nel[A2]) = { | |
val (h1, h2) = asPair(head) | |
val (t1, t2) = tail.unzip | |
(new Nel(h1, t1), new Nel(h2, t2)) | |
} | |
override def unzip3[A1, A2, A3](implicit asTriple: A => (A1, A2, A3)): (Nel[A1], Nel[A2], Nel[A3]) = { | |
val (h1, h2, h3) = asTriple(head) | |
val (t1, t2, t3) = tail.unzip3 | |
(new Nel(h1, t1), new Nel(h2, t2), new Nel(h3, t3)) | |
} | |
override def map[B](f: A => B): Nel[B] = new Nel(f(head), tail.map(f)) | |
override def concat[B >: A](suffix: IterableOnce[B]): Nel[B] = new Nel(head, tail.concat(suffix)) | |
override def sorted[B >: A](implicit ord: Ordering[B]): Nel[A] = fromList(toList.sorted(ord)) | |
override def sortWith(lt: (A, A) => Boolean): Nel[A] = fromList(toList.sortWith(lt)) | |
override def sortBy[B](f: A => B)(implicit ord: Ordering[B]): Nel[A] = fromList(toList.sortBy(f)) | |
override def isEmpty: Boolean = false | |
override def className: String = "Nel" | |
override def iterator: Iterator[A] = toList.iterator | |
} | |
// Companion doesn't conform to any existing Factory trait. | |
// That's not the end of the world -- neither does MapView, IndexedSeqView, SeqView, IntMap, or AnyRefMap | |
object Nel { | |
def from[A](source: IterableOnce[A]): Option[Nel[A]] = source match { | |
case nel: Nel[A] => Some(nel) | |
case h :: t => Some(new Nel(h, t)) | |
case other => | |
val iter = other.iterator | |
if (iter.hasNext) { | |
val head = iter.next() | |
Some(new Nel(head, List.from(iter))) | |
} else None | |
} | |
def newBuilder[A]: mutable.Builder[A, Option[Nel[A]]] = List.newBuilder[A].mapResult { | |
case h :: t => Some(new Nel(h, t)) | |
case _ => None | |
} | |
// if you provide an initial element, we can create a builder for Nels | |
def newBuilder[A](head: A): mutable.Builder[A, Nel[A]] = List.newBuilder[A].mapResult(new Nel(head, _)) | |
def apply[A](head: A, tail: A*): Nel[A] = new Nel(head, tail.toList) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment