简体   繁体   English

如何使这个函数纯

[英]How to make this function pure

My understanding about pure functions are that the output of the function only depends on the input.我对纯函数的理解是函数的输出只取决于输入。 And they are referentially transparent.它们在引用上是透明的。

But then there are side effects that happens in our code.但是在我们的代码中会发生副作用。 Below is an example下面是一个例子

  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
    }

  }

Above is a basic example where we do multiple side effects (call to database).上面是一个基本示例,其中我们执行多种副作用(调用数据库)。

getLastShipment returns a Future. getLastShipment 返回一个 Future。 Does that makes is a pure function.这使得是一个纯函数。

If getLastShipment is not pure then how to make it pure???如果 getLastShipment 不纯,那么如何使其纯?

You're pretty close, you're already on the right path using Monad s and for-comprehensions , however, Future is fundamentally side-effecting, because it does not suspend its evaluation.你已经很接近了,你已经在使用Monad s 和for-comprehensions的正确道路上,但是, Future从根本上是副作用,因为它不会暂停它的评估。 (For further information, see my answer here . If you switch your function to use something like cats.effect.IO : (有关更多信息,请在此处查看我的回答。如果您将函数切换为使用cats.effect.IO类的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
}

Then this code is completely pure and referentially transparent.那么这段代码是完全纯粹的并且引用透明的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM