Skip to content

Commit

Permalink
Add Foldable[StreamT[F, ?]] instance.
Browse files Browse the repository at this point in the history
  • Loading branch information
kazzna committed Dec 3, 2015
1 parent 9c37cff commit 92759dc
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
12 changes: 12 additions & 0 deletions core/src/main/scala/scalaz/StreamT.scala
Expand Up @@ -120,6 +120,14 @@ sealed class StreamT[M[_], A](val step: M[StreamT.Step[A, StreamT[M, A]]]) {
_.foldLeft(z)((a, b) => f(b, a))
}

def foldMap[B](f: A => B)(implicit M: Foldable[M], B: Monoid[B]): B =
M.foldMap(step) {
_( yieldd = (a, s) => B.append(f(a), s.foldMap(f))
, skip = s => s.foldMap(f)
, done = B.zero
)
}

def length(implicit m: Monad[M]): M[Int] = {
def addOne(c: => Int, a: => A) = 1 + c
foldLeft(0)(addOne _)
Expand Down Expand Up @@ -175,6 +183,10 @@ sealed abstract class StreamTInstances extends StreamTInstances0 {
implicit def StreamTEqual[F[_], A](implicit E: Equal[F[Stream[A]]], F: Monad[F]): Equal[StreamT[F, A]] = E.contramap((_: StreamT[F, A]).toStream)
implicit def StreamTShow[F[_], A](implicit E: Show[F[Stream[A]]], F: Monad[F]): Show[StreamT[F, A]] = Contravariant[Show].contramap(E)((_: StreamT[F, A]).toStream)
implicit val StreamTHoist: Hoist[StreamT] = new StreamTHoist {}
implicit def StreamTFoldable[F[_]: Foldable]: Foldable[StreamT[F, ?]] =
new Foldable[StreamT[F, ?]] with Foldable.FromFoldMap[StreamT[F, ?]] {
override def foldMap[A, M: Monoid](s: StreamT[F, A])(f: A => M) = s.foldMap(f)
}
}

object StreamT extends StreamTInstances {
Expand Down
7 changes: 7 additions & 0 deletions tests/src/test/scala/scalaz/StreamTTest.scala
Expand Up @@ -47,12 +47,18 @@ object StreamTTest extends SpecLite {
Traverse[Stream].traverse(s)(i => l.map(_ + i)) :::
Traverse[Stream].traverse(s0)(i => l.map(_ + i))
)
}

"foldMap" ! forAll {
(s: Stream[Int]) =>
import scalaz.Scalaz._
StreamT.fromStream(s.some).foldMap(_.toString) must_==(s.foldMap(_.toString))
}

checkAll(equal.laws[StreamTOpt[Int]])
checkAll(monoid.laws[StreamTOpt[Int]])
checkAll(monadPlus.laws[StreamTOpt])
checkAll(foldable.laws[StreamTOpt])

object instances {
def semigroup[F[_]: Functor, A] = Semigroup[StreamT[F, A]]
Expand All @@ -62,6 +68,7 @@ object StreamTTest extends SpecLite {
def plus[F[_]: Functor] = Plus[StreamT[F, ?]]
def monad[F[_]: Applicative] = Monad[StreamT[F, ?]]
def monadPlus[F[_]: Applicative] = MonadPlus[StreamT[F, ?]]
def foldable[F[_]: Foldable] = Foldable[StreamT[F, ?]]

// checking absence of ambiguity
def semigroup[F[_]: Applicative, A] = Semigroup[StreamT[F, A]]
Expand Down

0 comments on commit 92759dc

Please sign in to comment.