我想使用State monad来实现第三方API提供的数据的缓存。让我们假设方法getThirdPartyData(key: String)
首先检查缓存,然后如果它不存在那么应该向API发出请求。我想到的第一个也是最天真的实现是将状态包含在Future中 -
Future[State[Cache, ThirdPartyData]]
但这不正确,因为当请求失败时,您将丢失缓存(getThirdPartyData
将返回Failure
)。
我想到的第二个选项是延伸,或者更确切地说重新定义状态monad - s => Future[(s,a)]
,而不是s => (s,a)
,但我认为这是非常受欢迎的问题所以scalaz
可能有一些已定义的方法来解决这个问题。
任何帮助都非常感谢!
答案 0 :(得分:5)
这是您要找的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)