Setup:
import scalaz._; import Scalaz._
case class Foo(map: Map[Int, String] = Map.empty, set: Set[Int] = Set.empty)
val `foo.map`: Lens[Foo, Map[Int, String]] = Lens.lensu((f, m) => f.copy(map = m), _.map)
val `foo.set`: Lens[Foo, Set[Int]] = Lens.lensu((f, s) => f.copy(set = s), _.set)
case class Bar(cond: Boolean)
val listOfBars = List(Bar(true), Bar(false))
Now this doesn't compile
listOfBars.runTraverseS[Foo, Unit](Foo()) { bar =>
if (bar.cond)
`foo.map` += 1 -> "a"
else
`foo.set` += 2
}
This issue is that a Lens[Foo, Map[K, V]].+= returns a State[Foo, Map[K, V]] whereas Lens[Foo, Set[A]].+= returns a State[Foo, Set[A]]. Recall that State[S, A] is invariant in A
However, this does compile:
listOfBars.runTraverseS[Foo, Unit](Foo()) { bar =>
for {
_ <- State.init[Foo]
x <- {
if (bar.cond)
`foo.map` += 1 -> "a"
else
`foo.set` += 2
}
} yield ()
}
- Why does this compile?
- What is the type of
x? (IDEA says it'stype $_1or something like that - I assume that it is not a denotable type)
EDIT
If I change yield () to yield println(x) and println the output of the for comprehension, I get this:
Map(1 -> a)
Set(2)
(Foo(Map(1 -> a),Set(2)),List((), ()))