-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Redesign NonEmptyLazyList to be maximally lazy
#4504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 9 commits
ef284ec
ad69065
3c5e564
d80d959
e948a1d
10f8c21
4f842eb
df8778e
5e6b46e
29d095b
46754d4
2bb52cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,11 +47,13 @@ object NonEmptyLazyList extends NonEmptyLazyListInstances { | |
| s.asInstanceOf[LazyList[A]] | ||
|
|
||
| def fromLazyList[A](as: LazyList[A]): Option[NonEmptyLazyList[A]] = | ||
| if (as.nonEmpty) Option(create(as)) else None | ||
| if (as.nonEmpty) Some(create(as)) else None | ||
|
|
||
| def fromLazyListUnsafe[A](ll: LazyList[A]): NonEmptyLazyList[A] = | ||
| if (ll.nonEmpty) create(ll) | ||
| else throw new IllegalArgumentException("Cannot create NonEmptyLazyList from empty LazyList") | ||
| def fromLazyListUnsafe[A](ll: LazyList[A]): NonEmptyLazyList[A] = { | ||
| @inline def ex = new IllegalArgumentException("Cannot create NonEmptyLazyList from empty LazyList") | ||
| if (ll.knownSize == 0) throw ex | ||
| else create({ if (ll.isEmpty) throw ex else ll } #::: LazyList.empty) | ||
| } | ||
|
|
||
| def fromNonEmptyList[A](as: NonEmptyList[A]): NonEmptyLazyList[A] = | ||
| create(LazyList.from(as.toList)) | ||
|
|
@@ -62,14 +64,70 @@ object NonEmptyLazyList extends NonEmptyLazyListInstances { | |
| def fromSeq[A](as: Seq[A]): Option[NonEmptyLazyList[A]] = | ||
| if (as.nonEmpty) Option(create(LazyList.from(as))) else None | ||
|
|
||
| def fromLazyListPrepend[A](a: A, ca: LazyList[A]): NonEmptyLazyList[A] = | ||
| create(a +: ca) | ||
| def fromLazyListPrepend[A](a: => A, ll: => LazyList[A]): NonEmptyLazyList[A] = | ||
| create(a #:: ll) | ||
|
|
||
| @deprecated("Use overload with by-name args", "2.11.0") | ||
| def fromLazyListPrepend[A]()(a: A, ll: LazyList[A]): NonEmptyLazyList[A] = | ||
| fromLazyListPrepend(a, ll) | ||
|
|
||
| def fromLazyListAppend[A](ll: => LazyList[A], a: => A): NonEmptyLazyList[A] = | ||
| create(ll #::: a #:: LazyList.empty) | ||
|
|
||
| def fromLazyListAppend[A](ca: LazyList[A], a: A): NonEmptyLazyList[A] = | ||
| create(ca :+ a) | ||
| @deprecated("Use overload with by-name args", "2.11.0") | ||
| def fromLazyListAppend[A]()(ll: LazyList[A], a: A): NonEmptyLazyList[A] = | ||
| fromLazyListAppend(ll, a) | ||
|
|
||
| def apply[A](a: => A, as: A*): NonEmptyLazyList[A] = | ||
| create(LazyList.concat(LazyList(a), LazyList.from(as))) | ||
| create(a #:: LazyList.from(as)) | ||
|
|
||
| /** | ||
| * Wraps a `LazyList` that may or may not be empty so that individual | ||
| * elements or `NonEmptyLazyList`s can be prepended to it to construct a | ||
| * result that is guaranteed not to be empty without evaluating any elements. | ||
| */ | ||
| def maybe[A](ll: => LazyList[A]): Maybe[A] = new Maybe(() => ll) | ||
|
|
||
| /** | ||
| * Wrapper around a `LazyList` that may or may not be empty so that individual | ||
| * elements or `NonEmptyLazyList`s can be prepended to it to construct a | ||
| * result that is guaranteed not to be empty without evaluating any elements. | ||
| */ | ||
| final class Maybe[A] private[NonEmptyLazyList] (mkLL: () => LazyList[A]) { | ||
| // because instances of this class are created explicitly, they might be | ||
| // reused, and we don't want to re-evaluate `mkLL` | ||
| private[this] lazy val ll = mkLL() | ||
|
|
||
| /** Prepends a single element, yielding a `NonEmptyLazyList`. */ | ||
| def #::[AA >: A](elem: => AA): NonEmptyLazyList[AA] = | ||
| create(elem #:: ll) | ||
|
|
||
| /** Prepends a `LazyList`, yielding another [[Maybe]]. */ | ||
| def #:::[AA >: A](prefix: => LazyList[AA]): Maybe[AA] = | ||
| new Maybe(() => prefix #::: ll) | ||
|
||
|
|
||
| /** Prepends a `NonEmptyLazyList`, yielding a `NonEmptyLazyList`. */ | ||
| def #:::[AA >: A](prefix: => NonEmptyLazyList[AA])(implicit d: DummyImplicit): NonEmptyLazyList[AA] = | ||
| create(prefix.toLazyList #::: ll) | ||
| } | ||
|
|
||
| final class Deferrer[A] private[NonEmptyLazyList] (private val nell: () => NonEmptyLazyList[A]) extends AnyVal { | ||
|
|
||
| /** Prepends a single element. */ | ||
| def #::[AA >: A](elem: => AA): NonEmptyLazyList[AA] = | ||
| create(elem #:: nell().toLazyList) | ||
|
|
||
| /** Prepends a `LazyList`. */ | ||
| def #:::[AA >: A](prefix: => LazyList[AA]): NonEmptyLazyList[AA] = | ||
| create(prefix #::: nell().toLazyList) | ||
NthPortal marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| /** Prepends a `NonEmptyLazyList`. */ | ||
| def #:::[AA >: A](prefix: => NonEmptyLazyList[AA])(implicit d: DummyImplicit): NonEmptyLazyList[AA] = | ||
| create(prefix.toLazyList #::: nell().toLazyList) | ||
|
||
| } | ||
|
|
||
| implicit def toDeferrer[A](nell: => NonEmptyLazyList[A]): Deferrer[A] = | ||
| new Deferrer(() => nell) | ||
|
|
||
| implicit def catsNonEmptyLazyListOps[A](value: NonEmptyLazyList[A]): NonEmptyLazyListOps[A] = | ||
| new NonEmptyLazyListOps(value) | ||
NthPortal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
@@ -110,18 +168,16 @@ class NonEmptyLazyListOps[A](private val value: NonEmptyLazyList[A]) | |
| * Returns a new NonEmptyLazyList consisting of `a` followed by this | ||
| */ | ||
| final def prepend[AA >: A](a: AA): NonEmptyLazyList[AA] = | ||
| create(a #:: toLazyList) | ||
| create(toLazyList.prepended(a)) | ||
NthPortal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /** | ||
| * Alias for [[prepend]]. | ||
| */ | ||
| final def +:[AA >: A](a: AA): NonEmptyLazyList[AA] = | ||
| prepend(a) | ||
|
|
||
| /** | ||
| * Alias for [[prepend]]. | ||
| */ | ||
| final def #::[AA >: A](a: AA): NonEmptyLazyList[AA] = | ||
| @deprecated("use Deferrer construction instead") | ||
| final def #::[AA >: A]()(a: AA): NonEmptyLazyList[AA] = | ||
| prepend(a) | ||
NthPortal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /** | ||
|
|
@@ -137,54 +193,108 @@ class NonEmptyLazyListOps[A](private val value: NonEmptyLazyList[A]) | |
| append(a) | ||
|
|
||
| /** | ||
| * concatenates this with `ll` | ||
| * Concatenates this with `ll`; equivalent to `appendLazyList` | ||
| */ | ||
| final def concat[AA >: A](ll: LazyList[AA]): NonEmptyLazyList[AA] = | ||
| create(toLazyList ++ ll) | ||
| final def concat[AA >: A](ll: => LazyList[AA]): NonEmptyLazyList[AA] = | ||
| appendLazyList(ll) | ||
|
|
||
| @deprecated("Use overload with by-name args", "2.11.0") | ||
| final private[data] def concat[AA >: A]()(ll: LazyList[AA]): NonEmptyLazyList[AA] = | ||
| concat(ll) | ||
|
|
||
| /** | ||
| * Concatenates this with `nell` | ||
| * Alias for `concat` | ||
| */ | ||
| final def concatNell[AA >: A](nell: NonEmptyLazyList[AA]): NonEmptyLazyList[AA] = | ||
| create(toLazyList ++ nell.toLazyList) | ||
| final def ++[AA >: A](ll: => LazyList[AA]): NonEmptyLazyList[AA] = | ||
| concat(ll) | ||
|
|
||
| /** | ||
| * Alias for concatNell | ||
| * Concatenates this with `nell`; equivalent to `appendNell` | ||
| */ | ||
| final def ++[AA >: A](nell: NonEmptyLazyList[AA]): NonEmptyLazyList[AA] = | ||
| final def concatNell[AA >: A](nell: => NonEmptyLazyList[AA]): NonEmptyLazyList[AA] = | ||
| appendNell(nell) | ||
|
|
||
| @deprecated("Use overload with by-name args", "2.11.0") | ||
| final private[data] def concatNell[AA >: A]()(nell: NonEmptyLazyList[AA]): NonEmptyLazyList[AA] = | ||
| concatNell(nell) | ||
|
|
||
| /** | ||
| * Alias for `concatNell` | ||
| */ | ||
| final def ++[AA >: A](nell: => NonEmptyLazyList[AA])(implicit d: DummyImplicit): NonEmptyLazyList[AA] = | ||
| concatNell(nell) | ||
|
|
||
| @deprecated("Use overload with by-name args", "2.11.0") | ||
| final private[data] def ++[AA >: A]()(ll: NonEmptyLazyList[AA]): NonEmptyLazyList[AA] = | ||
| ++(ll) | ||
|
|
||
| /** | ||
| * Appends the given LazyList | ||
| */ | ||
| final def appendLazyList[AA >: A](nell: LazyList[AA]): NonEmptyLazyList[AA] = | ||
| if (nell.isEmpty) value | ||
| else create(toLazyList ++ nell) | ||
| final def appendLazyList[AA >: A](ll: => LazyList[AA]): NonEmptyLazyList[AA] = | ||
| create(toLazyList #::: ll) | ||
|
|
||
| @deprecated("Use overload with by-name args", "2.11.0") | ||
| final private[data] def appendLazyList[AA >: A]()(ll: LazyList[AA]): NonEmptyLazyList[AA] = | ||
| appendLazyList(ll) | ||
|
|
||
| /** | ||
| * Alias for `appendLazyList` | ||
| */ | ||
| final def :++[AA >: A](c: LazyList[AA]): NonEmptyLazyList[AA] = | ||
| appendLazyList(c) | ||
| final def :++[AA >: A](ll: => LazyList[AA]): NonEmptyLazyList[AA] = | ||
| appendLazyList(ll) | ||
NthPortal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| @deprecated("Use overload with by-name args", "2.11.0") | ||
| final private[data] def :++[AA >: A]()(ll: LazyList[AA]): NonEmptyLazyList[AA] = | ||
| appendLazyList(ll) | ||
|
|
||
| /** | ||
| * Prepends the given NonEmptyLazyList | ||
| */ | ||
| final def appendNell[AA >: A](nell: => NonEmptyLazyList[AA]): NonEmptyLazyList[AA] = | ||
| create(toLazyList #::: nell.toLazyList) | ||
|
|
||
| /** | ||
| * Alias for `appendNell` | ||
| */ | ||
| final def :++[AA >: A](nell: => NonEmptyLazyList[AA])(implicit d: DummyImplicit): NonEmptyLazyList[AA] = | ||
| appendNell(nell) | ||
|
|
||
| @deprecated("Use overload with by-name args", "2.11.0") | ||
| final private[data] def ++:[AA >: A]()(ll: NonEmptyLazyList[AA]): NonEmptyLazyList[AA] = | ||
| ++:(ll) | ||
|
|
||
| /** | ||
| * Prepends the given LazyList | ||
| */ | ||
| final def prependLazyList[AA >: A](c: LazyList[AA]): NonEmptyLazyList[AA] = | ||
| if (c.isEmpty) value | ||
| else create(c ++ toLazyList) | ||
| final def prependLazyList[AA >: A](ll: => LazyList[AA]): NonEmptyLazyList[AA] = | ||
| create(ll #::: toLazyList) | ||
|
|
||
| @deprecated("Use overload with by-name args", "2.11.0") | ||
| final private[data] def prependLazyList[AA >: A]()(ll: LazyList[AA]): NonEmptyLazyList[AA] = | ||
| prependLazyList(ll) | ||
|
|
||
| /** | ||
| * Alias for `prependLazyList` | ||
| */ | ||
| final def ++:[AA >: A](ll: => LazyList[AA]): NonEmptyLazyList[AA] = | ||
| prependLazyList(ll) | ||
|
|
||
| /** | ||
| * Prepends the given NonEmptyLazyList | ||
| */ | ||
| final def prependNell[AA >: A](c: NonEmptyLazyList[AA]): NonEmptyLazyList[AA] = | ||
| create(c.toLazyList ++ toLazyList) | ||
| final def prependNell[AA >: A](nell: => NonEmptyLazyList[AA]): NonEmptyLazyList[AA] = | ||
| create(nell.toLazyList #::: toLazyList) | ||
|
|
||
| @deprecated("Use overload with by-name args", "2.11.0") | ||
| final private[data] def prependNell[AA >: A]()(nell: NonEmptyLazyList[AA]): NonEmptyLazyList[AA] = | ||
| prependNell(nell) | ||
|
|
||
| /** | ||
| * Alias for `prependNell` | ||
| */ | ||
| final def ++:[AA >: A](c: NonEmptyLazyList[AA]): NonEmptyLazyList[AA] = | ||
| prependNell(c) | ||
| final def ++:[AA >: A](nell: => NonEmptyLazyList[AA])(implicit d: DummyImplicit): NonEmptyLazyList[AA] = | ||
| prependNell(nell) | ||
|
|
||
| /** | ||
| * Converts this NonEmptyLazyList to a `NonEmptyList`. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.