This prints out the unchanged value of 5:
import zio.stm._
import zio.Console
import zio.Runtime.{default => rt}
class TInt(n: TRef[Int]):
def ++(): USTM[Unit] = n.update(_ + 1)
override def toString: String = n.toString
object TInt:
def make(n: Int): USTM[TInt] = TRef.make(n).map(TInt(_))
class Client:
val stmN: USTM[TInt] = TInt.make(5)
def increment: USTM[Unit] = stmN.flatMap(_.++())
val c = Client()
rt.unsafeRun(for
_ <- c.increment.commit
n <- c.stmN.commit
_ <- Console.printLine(n)
yield ())
How can I (w/ minimal structural changes) get it to print out the incremented value instead? With some testing, I know that TInt is solid. The issue, I suspect, has to do w/ Client.stmN being a USTM and not reflecting the underlying mutation.
Undressed
stmN: STM[TInt]and now it's simplyn: Tintand being tracked as a constructor parameter. This requires construction of theClientto be pulled into, effectively, aTRef.map:The effect of this is that
cis now part of the returning value w/inunsafeRun. Seems likeClientneeded to be wrapped w/ aUSTMin order for its mutability to be taken seriously. In general, it is best, I have found, to not spread transactions amongst various classes w/in composition trees. While it does make for a nice OO design, it makes it difficult to get the mutability desired. Instead, try to keep everything on the same class and just usestm.T* as the state.