diff --git a/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala b/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala index 846b960ef1..5a99712bb6 100644 --- a/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala +++ b/core/src/main/scala-2.13+/cats/data/NonEmptyLazyList.scala @@ -274,6 +274,12 @@ class NonEmptyLazyListOps[A](private val value: NonEmptyLazyList[A]) final def foldRight[B](z: B)(f: (A, B) => B): B = toLazyList.foldRight(z)(f) + final def scanLeft[B](b: B)(f: (B, A) => B): NonEmptyLazyList[B] = + create(toLazyList.scanLeft(b)(f)) + + final def scanLeftTail[B](b: B)(f: (B, A) => B): NonEmptyLazyList[B] = + create(toLazyList.scanLeft(b)(f).tail) + /** * Left-associative reduce using f. */ diff --git a/core/src/main/scala/cats/data/NonEmptyChain.scala b/core/src/main/scala/cats/data/NonEmptyChain.scala index 3742a92268..af0d985e17 100644 --- a/core/src/main/scala/cats/data/NonEmptyChain.scala +++ b/core/src/main/scala/cats/data/NonEmptyChain.scala @@ -302,6 +302,20 @@ class NonEmptyChainOps[A](private val value: NonEmptyChain[A]) final def foldLeft[B](b: B)(f: (B, A) => B): B = toChain.foldLeft(b)(f) + final def scanLeft[B](b: B)(f: (B, A) => B): NonEmptyChain[B] = { + var current = b + var result = Chain.one[B](b) + val iter = toChain.iterator + while (iter.hasNext) { + current = f(current, iter.next()) + result = result :+ current + } + create(result) + } + + final def scanLeftTail[B](b: B)(f: (B, A) => B): NonEmptyChain[B] = + create(scanLeft(b)(f).tail) + /** * Right-associative fold using f. */ diff --git a/core/src/main/scala/cats/data/NonEmptyCollection.scala b/core/src/main/scala/cats/data/NonEmptyCollection.scala index 72c158a84e..c3601d962d 100644 --- a/core/src/main/scala/cats/data/NonEmptyCollection.scala +++ b/core/src/main/scala/cats/data/NonEmptyCollection.scala @@ -46,6 +46,8 @@ private[cats] trait NonEmptyCollection[+A, U[+_], NE[+_]] extends Any { def forall(p: A => Boolean): Boolean def foldLeft[B](b: B)(f: (B, A) => B): B + def scanLeft[B](b: B)(f: (B, A) => B): NE[B] + def scanLeftTail[B](b: B)(f: (B, A) => B): NE[B] def reduce[AA >: A](implicit S: Semigroup[AA]): AA def zipWith[B, C](b: NE[B])(f: (A, B) => C): NE[C] diff --git a/core/src/main/scala/cats/data/NonEmptyList.scala b/core/src/main/scala/cats/data/NonEmptyList.scala index c2e86caa60..097afcd219 100644 --- a/core/src/main/scala/cats/data/NonEmptyList.scala +++ b/core/src/main/scala/cats/data/NonEmptyList.scala @@ -302,6 +302,12 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) extends NonEmptyCollec def foldRight[B](lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = Foldable[List].foldRight(toList, lb)(f) + def scanLeft[B](b: B)(f: (B, A) => B): NonEmptyList[B] = + NonEmptyList(b, tail.scanLeft(f(b, head))(f)) + + def scanLeftTail[B](b: B)(f: (B, A) => B): NonEmptyList[B] = + NonEmptyList.fromListUnsafe(tail.scanLeft(f(b, head))(f)) + /** * Left-associative reduce using f. */ diff --git a/core/src/main/scala/cats/data/NonEmptySeq.scala b/core/src/main/scala/cats/data/NonEmptySeq.scala index f43ef75ac4..9ec273b1bb 100644 --- a/core/src/main/scala/cats/data/NonEmptySeq.scala +++ b/core/src/main/scala/cats/data/NonEmptySeq.scala @@ -178,6 +178,12 @@ final class NonEmptySeq[+A] private (val toSeq: Seq[A]) extends AnyVal with NonE def foldLeft[B](b: B)(f: (B, A) => B): B = toSeq.foldLeft(b)(f) + def scanLeft[B](b: B)(f: (B, A) => B): NonEmptySeq[B] = + new NonEmptySeq(toSeq.scanLeft(b)(f)) + + def scanLeftTail[B](b: B)(f: (B, A) => B): NonEmptySeq[B] = + new NonEmptySeq(toSeq.scanLeft(b)(f).tail) + /** * Right-associative fold using f. */ diff --git a/core/src/main/scala/cats/data/NonEmptyVector.scala b/core/src/main/scala/cats/data/NonEmptyVector.scala index 583dd63612..ff9fabc2e2 100644 --- a/core/src/main/scala/cats/data/NonEmptyVector.scala +++ b/core/src/main/scala/cats/data/NonEmptyVector.scala @@ -188,6 +188,12 @@ final class NonEmptyVector[+A] private (val toVector: Vector[A]) def foldLeft[B](b: B)(f: (B, A) => B): B = toVector.foldLeft(b)(f) + def scanLeft[B](b: B)(f: (B, A) => B): NonEmptyVector[B] = + NonEmptyVector.fromVectorUnsafe(toVector.scanLeft(b)(f)) + + def scanLeftTail[B](b: B)(f: (B, A) => B): NonEmptyVector[B] = + NonEmptyVector.fromVectorUnsafe(tail.scanLeft(f(b, head))(f)) + /** * Right-associative fold using f. */