【问题标题】:Appropriate return type for an async http request? IO[Future[Response]] or Future[Response]? Or some alternative?异步 http 请求的适当返回类型? IO[Future[Response]] 还是 Future[Response]?或者有什么替代品?
【发布时间】:2015-06-08 15:02:22
【问题描述】:

对于以下假设函数(在 scala 中),函数式编程中合适的返回类型是什么?

def execute(req: HttpRequest): <UnknownResultType>

我假设IO[Future[Response]],因为我们既有网络副作用也有异步性。

由于这可能有点麻烦(一个 monad 包裹在一个 monad 中,即使使用 monad 转换器),在 FP 中是否有更好的抽象来处理这个问题?

【问题讨论】:

  • Future 经常像 Scala 中的 IO 一样使用(即表示任何旧的效果)。即使在 Scalaz 中,这种惯用类型也是 Task,这在相关方面等同于标准库的 Future
  • @TravisBrown 但我认为这不会是参照透明的。因为我们不能用调用一次的结果替换多次调用execute(req),这将是一个未来。具体来说,execute(req) 的每次调用都会发送一个单独的 http 请求,而未来的结果只会执行一次并缓存结果。另一方面,使用 IO 会保留 RT。
  • 好吧,我的“在相关方面”被夸大了一点——你说得对,Scala 的 Future 没有给你 RT(而 Task 有)。无论如何,我认为您可能不想要IOFuture 的表示,您想要Future 的RT 版本(如Task)。
  • @TravisBrown 我认为您可以将两个 cmets 结合起来作为有效答案。

标签: scala functional-programming monads future scalaz


【解决方案1】:

正如@Travis Brown 所说,在 Scala 中返回纯异步计算最惯用的方法是使用 scalaz.concurrent.Task,您可以在 scalaz-concurrent 库中找到它。

使用Task,您的函数将如下所示:

def execute(req: HttpRequest): Task[Response]

execute 是一个纯函数:在调用Task.run 或类似方法之前不会产生副作用。

有关Task 的详细介绍,请参阅this great article

【讨论】:

    猜你喜欢
    • 2021-10-07
    • 1970-01-01
    • 2020-11-19
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 2016-05-09
    相关资源
    最近更新 更多