我正在阅读此博客post,声称Futures不具有“功能性”,因为它们只是副作用计算的包装。例如,它们包含RPC调用,HTTP请求等。是否正确?

该博客文章给出了以下示例:

def twoUsersFeed(a: UserHandle, b: UserHandle)
                (implicit ec: ExecutionContext): Future[Html] =
  for {
    feedA <- usersFeed(a)
    feedB <- usersFeed(b)
  } yield feedA ++ feedB
you lose the desired property: consistent results (the referential transparency). Also you lose the property of making as few requests as possible. It is difficult to use multi-valued requests and have composable code.
恐怕我不明白。您能解释一下在这种情况下我们如何丢失consistent result吗?

最佳答案

该博客文章未能在Future本身和它的常用方式IMO之间做出适当的区分。如果您只写过称为纯总函数的Future,则可以使用Future编写纯功能代码;这样的代码在每个遥不可及的意义上都是参照透明的,并且是“功能性的”。

的确,如果将Future与具有副作用的方法一起使用,那么Future可以使您有限地控制副作用。如果创建包裹webClient.getFuture,则创建该Future将发送HTTP调用。但这不是关于webClient.get的事实,这是关于for的事实!

在这篇博客文章中有一点道理。通过例如完全将表示您的计算与执行完全分开Free monad,可以产生更高效和更可测试的代码。例如。您可以创建一种“查询语言”,在其中无需进行实际操作即可表达“获取A和B的所有共同 friend 的个人资料照片”之类的操作。这使您更容易测试您的逻辑是否正确(因为非常容易进行例如可以“运行”相同查询的测试实现,甚至可以直接检查“查询对象”),而且,正如我认为的博客文章一样正在尝试建议,这意味着您可以例如合并多个请求以获取相同的配置文件。 (这甚至不是纯粹的功能编程问题-一些OO书籍都有“命令模式”的想法-尽管IME功能编程工具(如yield/fetchProfile语法使以这种方式工作变得更加容易)。而如果您拥有的只是一个Future方法,该方法在运行时会立即触发HTTP请求,然后,如果您的代码逻辑两次请求相同的配置文件,则无法避免两次获取相同的配置文件。

但这并不是真正的ojit_code本身,而IMO此博客文章更令人困惑,而不是有所帮助。

关于scala - Scala的 future 真的有用吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27591599/

10-16 02:37