Skip to content

Commit

Permalink
Add listen for Writer and WriterT
Browse files Browse the repository at this point in the history
  • Loading branch information
jooohn committed Jun 27, 2019
1 parent 162ee0f commit 1ad001e
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
8 changes: 8 additions & 0 deletions core/src/main/scala/cats/data/WriterT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ final case class WriterT[F[_], L, V](run: F[(L, V)]) {
def value(implicit functorF: Functor[F]): F[V] =
functorF.map(run)(_._2)

def listen(implicit F: Functor[F]): WriterT[F, L, (V, L)] =
WriterT(F.map(run) {
case (l, v) => (l, (v, l))
})

def ap[Z](f: WriterT[F, L, V => Z])(implicit F: Apply[F], L: Semigroup[L]): WriterT[F, L, Z] =
WriterT(F.map2(f.run, run) {
case ((l1, fvz), (l2, v)) => (L.combine(l1, l2), fvz(v))
Expand Down Expand Up @@ -542,4 +547,7 @@ private[data] trait WriterTFunctions {

def valueT[F[_], L, V](vf: F[V])(implicit functorF: Functor[F], monoidL: Monoid[L]): WriterT[F, L, V] =
WriterT.putT[F, L, V](vf)(monoidL.empty)

def listen[F[_], L, V](writerTFLV: WriterT[F, L, V])(implicit functorF: Functor[F]): WriterT[F, L, (V, L)] =
writerTFLV.listen
}
3 changes: 3 additions & 0 deletions core/src/main/scala/cats/data/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ package object data {
def value[L: Monoid, V](v: V): Writer[L, V] = WriterT.value(v)

def tell[L](l: L): Writer[L, Unit] = WriterT.tell(l)

def listen[L, V](writer: Writer[L, V]): Writer[L, (V, L)] =
WriterT.listen(writer)
}

type IndexedState[S1, S2, A] = IndexedStateT[Eval, S1, S2, A]
Expand Down
17 changes: 17 additions & 0 deletions tests/src/test/scala/cats/tests/WriterTSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ class WriterTSuite extends CatsSuite {
}
}

test("value + listen + map(_._1) + value is identity") {
forAll { (i: Int) =>
WriterT.value[Id, Int, Int](i).listen.map(_._1).value should ===(i)
}
}

test("tell + listen + map(_._2) + value is identity") {
forAll { (i: Int) =>
WriterT.tell[Id, Int](i).listen.map(_._2).value should ===(i)
}
}

test("Writer.pure and WriterT.liftF are consistent") {
forAll { (i: Int) =>
val writer: Writer[String, Int] = Writer.value(i)
Expand All @@ -91,6 +103,11 @@ class WriterTSuite extends CatsSuite {
Writer.tell("foo").written should ===("foo")
}

test("listen returns a tuple of value and log") {
val w: Writer[String, Int] = Writer("foo", 3)
w.listen should ===(Writer("foo", (3, "foo")))
}

test("mapK consistent with f(value)+pure") {
val f: List ~> Option = λ[List ~> Option](_.headOption)
forAll { (writert: WriterT[List, String, Int]) =>
Expand Down

0 comments on commit 1ad001e

Please sign in to comment.