我想使用State monad对从第三方API提供的数据实施缓存。假设方法getThirdPartyData(key: String)首先检查缓存,然后如果不存在,则应该向API发出请求。我想到的第一个也是最幼稚的实现是将State类型包含在Future中-

Future[State[Cache, ThirdPartyData]]


但这是不正确的,因为当请求失败时,您将丢失缓存(getThirdPartyData将返回Failure)。

我想到的第二个选择是扩展,或者重新定义State monad-s => Future[(s,a)],而不是s => (s,a),但是我认为这是一个非常普遍的问题,因此scalaz可能已经有了解决此问题的已定义方法。

任何帮助,不胜感激!

最佳答案

这是您要查找的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)

07-26 05:54