我对纯函数的理解是函数的输出仅取决于输入。而且他们的参考是透明的。
但是我们的代码中会出现副作用。以下是一个例子
import scala.concurrent.Future
case class Customer(fName: String, lName: String)
case class Order(orderId: Int, item: String, quantity: Int)
case class Shipment(shipmentId: Int, orderId: Int, address: String)
trait CustomerRepo {
def findCustomer(userId: String): Future[Customer] = ???
def findLastOrder(customer: Customer): Future[Order] = ???
def findShipment(orderId: Int): Future[Shipment] = ???
}
class ShoppingApp(customerRepo: CustomerRepo) {
def getLastShipment(userId: String): Future[Shipment] = {
for {
customer <- customerRepo.findCustomer(userId)
lastOrder <- customerRepo.findLastOrder(customer)
shipment <- customerRepo.findShipment(lastOrder.orderId)
} yield shipment
}
}
上面是我们做多个副作用(调用数据库)的基本示例。
getLastShipment返回Future。这是否是一个纯粹的功能。
如果getLastShipment不纯,那么如何让它变得纯粹
答案 0 :(得分:1)
你非常接近,你已经使用Monad
和for-comprehensions
走在了正确的道路上,但是,Future
从根本上是副作用,因为它没有暂停其评价。 (有关详细信息,请参阅我的回答here。
如果您将功能切换为cats.effect.IO
:
def getLastShipment(userId: String): IO[Shipment] = {
for {
customer <- customerRepo.findCustomer(userId)
lastOrder <- customerRepo.findLastOrder(customer)
shipment <- customerRepo.findShipment(lastOrder.orderId)
} yield shipment
}
然后这段代码完全纯粹且引用透明。