gpt4 book ai didi

scala - 像 Eithers 这样的错误处理 monad 如何实现引用透明性?

转载 作者:行者123 更新时间:2023-12-01 01:48:43 27 4
gpt4 key购买 nike

通过阅读有关 FP 的内容,我对消除副作用的好处的理解是,如果我们所有的函数都是纯粹的/具有引用透明性(只有在没有副作用的情况下才能实现的东西),那么我们的函数就更容易测试、调试、重用,并且更加模块化。

由于异常是副作用的一种形式,因此我们需要避免抛出异常。显然,我们仍然需要能够在出现问题时终止进程,因此 FP 使用 monad 来实现引用透明性和处理异常的能力。

我感到困惑的是 monad 到底是如何实现这一点的。假设我有使用 scalaz 的代码

def couldThrowException: Exception \/ Boolean = ??
val f = couldThrowException()
val g = couldThrowException()

由于 couldThrowException 可能会返回异常,因此不能保证 fg 会相同。 f 可以是 \/-(true)g 可以是 -\/(NullPointerException)。由于 couldThrowException 可以使用相同的输入返回不同的值,因此它不是纯函数。使用 monad 来保持我们的函数纯净不是重点吗?

最佳答案

f()g()给定相同的输入,应该计算出相同的值。

在纯 FP 中,没有参数的函数每次调用时都必须计算出相同的结果。所以如果你的 couldThrowException 就不是纯粹的 FP有时返回 \/-(true)有时-\/(NullPointerException) .

返回 Either if couldThrowException 更有意义接受一个参数。如果它是纯函数,它将具有引用透明度,因此某些输入将始终导致 \/-(true)并且某些输入将始终导致 -\/(NullPointerException) .

在 Scala 中,您可能使用的函数不是纯粹的,并且不是引用透明的。也许它是一个Java 类。也许它使用了 Scala 的一部分,但并不纯粹。

但我猜您对在纯 FP 世界和不纯库之间架起桥梁感兴趣。 IO 就是一个典型的例子。 println可能会因各种原因而失败 - 权限、文件系统已满等。

在 FP 中处理此问题的经典方法是使用 IO 函数,该函数将“世界”状态作为输入参数,并返回 IO 调用的结果和新的“世界”状态。状态可以是由不纯语言的库代码支持的“假”值,但这意味着每次调用该函数时,您都会传递不同的状态,因此它是引用透明的。

通常,单子(monad)用于封装“世界”。

通过阅读 Haskell 的 IO monad,您可以了解有关此方法的更多信息。

核心 Scala IO 并不完全纯净,因此 println可能会抛出异常,因此,正如您所发现的,并不完全引用透明。 Scalaz提供类似于 Haskell 的 IO monad。

需要注意一件事,因为它会让很多初学者感到困惑:“世界”方法中没有任何东西需要 monad,并且当第一次学习 monad 是什么以及为什么时,IO 并不是最容易查看的 monad它们很有用。

关于scala - 像 Eithers 这样的错误处理 monad 如何实现引用透明性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55687335/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com