Ami*_*Mal 4 monads functional-programming scala
我当时正在读《Scala with Cats》一书,其中有这样一句话,我将在这里引用:
\n\n\n请注意,Scala\xe2\x80\x99s Futures 是纯函数式编程的一个很好的例子,因为它们是引用透明的。
\n
另外,还提供了一个示例,如下所示:
\nval future1 = {\n // Initialize Random with a fixed seed:\n val r = new Random(0L)\n // nextInt has the side-effect of moving to\n // the next random number in the sequence:\n val x = Future(r.nextInt)\n for {\n a <- x\n b <- x\n } yield (a, b)\n}\nval future2 = {\n val r = new Random(0L)\n for {\n a <- Future(r.nextInt)\n b <- Future(r.nextInt)\n } yield (a, b)\n}\nval result1 = Await.result(future1, 1.second)\n// result1: (Int, Int) = (-1155484576, -1155484576)\nval result2 = Await.result(future2, 1.second)\n// result2: (Int, Int) = (-1155484576, -723955400)\nRun Code Online (Sandbox Code Playgroud)\nr.nextInt我的意思是,我认为这是因为从来没有引用透明的事实,对吧?因为identity(r.nextInt)永远不会等于identity(r.nextInt),这是否意味着identity也不是引用透明的?(或 Identity monad,以便与 Future 进行更好的比较)。如果计算的表达式是 RT,那么 也Future将是 RT:
def foo(): Int = 42\n\nval x = Future(foo())\n\nAwait.result(x, ...) == Await.result(Future(foo()), ...) // true\nRun Code Online (Sandbox Code Playgroud)\n据我所知,几乎每个函数和 Monad 类型都应该是非 RT 的。或者说有什么特别的地方Future吗?我也阅读了这个问题及其答案,但找不到我要找的东西。
你实际上是对的,你正在触及 FP 最挑剔的点之一;至少在Scala中是这样。
从技术上讲,Future它本身就是RT。重要的是,与IO它不同的是,它不能将非 RT 的东西包装到 RT 描述中。但是,您可以对许多其他类型说同样的话,例如List, 或Option; 那么为什么人们不对此大惊小怪呢?
嗯,就像许多事情一样,细节决定成败。
List与or相反Option,Future通常与非 RT 事物一起使用;例如 HTTP 请求或数据库查询。因此,人们强调Future在这些情况下不能保证 RT。更重要的是,在代码库中
引入并发性(不要与并行性混淆)只有一个原因;否则,它将与 相同。因此,控制执行的时间和方式通常很重要。
这就是为什么猫建议在所有用例中使用FutureTryIOFuture
注意:您可以找到关于此cats PR的类似讨论及其链接讨论: https: //github.com/typelevel/cats/pull/4182