I would like to use State monad to implement caching for data provided from third party API. Let's imagine method getThirdPartyData(key: String)
which firstly checks cache then if it's not present there should make request to API. First and most naive implementation which came to my mind was enclosing State type within Future -
Future[State[Cache, ThirdPartyData]]
But it's not correct because when request fails you will lose your cache (getThirdPartyData
will return Failure
).
Second option which came to my mind was to extend, or rather redefine State monad - s => Future[(s,a)]
, instead of s => (s,a)
, but I thought that it's quite popular problem so scalaz
probably has some already defined way to solve this issue.
Any help greatly appreciated!
The state monad is a built in monad in Haskell that allows for chaining of a state variable (which may be arbitrarily complex) through a series of function calls, to simulate stateful code. It is defined as: newtype State s a = State { runState :: (s -> (a,s)) }
The Haskell type State describes functions that consume a state and produce both a result and an updated state, which are given back in a tuple. Here, s is the type of the state, and a the type of the produced result.
State is a structure that provides a functional approach to handling application state. State[S, A] is basically a function S => (S, A) , where S is the type that represents your state and A is the result the function produces.
Is this what you are looking for StateT[Future, Cache, ThirdPartyData]
?
implicit val m: Monoid[ThirdPartyData] = ...
val startState: Cache = ...
val l: List[StateT[Future, Cache, ThirdPartyData]] = ...
val result = l.sequenceU
.map { _.foldMap (identity)) }
.eval (startState)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With