Skip to content
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

Fix Foldabe#dropWhile_ bug. #623

Merged
merged 3 commits into from
Nov 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion core/src/main/scala/cats/Foldable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,22 @@ import simulacrum.typeclass
if (p(a)) buf += a else buf
}.toList

/**
* Convert F[A] to a List[A], retaining only initial elements which
* match `p`.
*/
def takeWhile_[A](fa: F[A])(p: A => Boolean): List[A] =
foldRight(fa, Now(List.empty[A])) { (a, llst) =>
if (p(a)) llst.map(a :: _) else Now(Nil)
}.value

/**
* Convert F[A] to a List[A], dropping all initial elements which
* match `p`.
*/
def dropWhile_[A](fa: F[A])(p: A => Boolean): List[A] =
foldLeft(fa, mutable.ListBuffer.empty[A]) { (buf, a) =>
if (buf.nonEmpty || p(a)) buf += a else buf
if (buf.nonEmpty || !p(a)) buf += a else buf
}.toList

/**
Expand Down
25 changes: 25 additions & 0 deletions tests/src/test/scala/cats/tests/FoldableTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import org.scalatest.prop.PropertyChecks
import org.scalacheck.{Arbitrary, Gen}
import org.scalacheck.Arbitrary.arbitrary

import cats.data.Streaming
import cats.std.all._
import cats.laws.discipline.arbitrary._

abstract class FoldableCheck[F[_]: Foldable](name: String)(implicit ArbFInt: Arbitrary[F[Int]]) extends CatsSuite with PropertyChecks {

def iterator[T](fa: F[T]): Iterator[T]
Expand All @@ -26,6 +30,7 @@ abstract class FoldableCheck[F[_]: Foldable](name: String)(implicit ArbFInt: Arb
fa.forall(_ > n) should === (iterator(fa).forall(_ > n))
fa.filter_(_ > n) should === (iterator(fa).filter(_ > n).toList)
fa.dropWhile_(_ > n) should === (iterator(fa).dropWhile(_ > n).toList)
fa.takeWhile_(_ > n) should === (iterator(fa).takeWhile(_ > n).toList)
}
}

Expand Down Expand Up @@ -96,3 +101,23 @@ class FoldableTestsAdditional extends CatsSuite {
assert(dangerous.toStreaming.take(3).toList == List(0, 1, 2))
}
}

class FoldableListCheck extends FoldableCheck[List]("list") {
def iterator[T](list: List[T]): Iterator[T] = list.iterator
}

class FoldableVectorCheck extends FoldableCheck[Vector]("vector") {
def iterator[T](vector: Vector[T]): Iterator[T] = vector.iterator
}

class FoldableStreamCheck extends FoldableCheck[Stream]("stream") {
def iterator[T](stream: Stream[T]): Iterator[T] = stream.iterator
}

class FoldableStreamingCheck extends FoldableCheck[Streaming]("streaming") {
def iterator[T](streaming: Streaming[T]): Iterator[T] = streaming.iterator
}

class FoldableMapCheck extends FoldableCheck[Map[Int, ?]]("map") {
def iterator[T](map: Map[Int, T]): Iterator[T] = map.iterator.map(_._2)
}