kyleg
02/10/2020, 5:16 PMStateT<ForIO, X, Y>
used to help manage state in my app, what is the benefit over a reader? when you .runM(IO.monad(), currentState)
it yields `(newState, someVal)`wrapped in IO
.
I’ve been managing state in my Android app with a private var
data class in my ViewModel representing a state object. For Id
operations, I can just use State<MyState, Unit>
to get back (newState, _)
and then myState = newState
. No problem.
But if I’m working with StateT<ForIO, MyState, Unit>
, it seems there could be race conditions doing it this way if two different state transformations are running in parallel since they’re both IO
. So I can’t just .unsafeRunAsync { … state = newState }
Instead, I can have these be StateT<ForIO, MyState, SomePartialStateChange>
and then take the partial state change and use that to update the viewmodel’s state outside the state transformation rather than reassigning the viewmodel’s state to the transformation’s returned MyState
.
But at that point, why not just use ReaderT<ForIO, MyState, SomePartialStateChange>
?
What’s the use case for StateT
if not for this example of IO
-wrapped state modification?kyleg
02/10/2020, 5:30 PMStateT<ForIO,Any,Any>
at all unless you know you’ll never be evaluating these in parallel?pakoito
02/10/2020, 6:06 PMpakoito
02/10/2020, 6:06 PMBob Glamm
02/10/2020, 6:08 PMRef
Bob Glamm
02/10/2020, 6:09 PMpakoito
02/10/2020, 6:09 PMpakoito
02/10/2020, 6:09 PMkyleg
02/10/2020, 6:11 PMdata class MyState(val id: Int, loaded: Boolean)
if you have
fun setId(id: Int) = StateT<ForIO, MyState, Unit> { ... iState.copy(id=id) toT Unit }
fun setLoaded(t: Boolean)= StateT<ForIO, MyState, Unit> { ... iState.copy(loaded=t) toT Unit}
and then when you .unsafeRunAsync
to get the data out of IO
and
{ (newState, _) ->
myCanonicalState = newState
}
then you have a race condition if setId
and setLoaded
can be run concurrently because one will overwrite the other’s changes.kyleg
02/10/2020, 6:12 PMReader
not letting you modify the context, can’t you have
data class Context(var id: Int)
and then inside your reader,
{ context -> context.id=5 }
and then anyone making reference to that context will have the updated context?
I’ve seen this recommended over StateT on the FP Complete blog (guy responsible for Haskell’s Yesod)kyleg
02/10/2020, 6:13 PMpakoito
02/10/2020, 6:13 PMpakoito
02/10/2020, 6:13 PMpakoito
02/10/2020, 6:14 PMpakoito
02/10/2020, 6:14 PMkyleg
02/10/2020, 6:16 PMBob Glamm
02/10/2020, 6:18 PMRef<ForIO, State<MyState, Unit>>
?Bob Glamm
02/10/2020, 6:18 PMkyleg
02/10/2020, 6:21 PMpakoito
02/10/2020, 6:22 PMkyleg
02/10/2020, 6:22 PMpakoito
02/10/2020, 6:22 PMkyleg
02/10/2020, 8:21 PMfx
to avoid a bunch of nested stuff. Soon will learn about Ref/AtomicReference. Thanks