functional scala—如何避免在可选映射上进行深度嵌套

functional scala—如何避免在可选映射上进行深度嵌套,scala,functional-programming,optional,flatmap,Scala,Functional Programming,Optional,Flatmap,我有一组按顺序完成的操作,但如果中间序列返回“null”,我希望提前中止操作(跳过后续步骤) 我想出了一个类似这样的函数,它给定一个输入参数,对Redis执行若干操作,并将返回一个存在的产品。因为有可能其中一个中间请求返回空值,所以整个操作可能会“失败”,我想缩短后面不必要的步骤 这里的筑巢越来越疯狂,我想让它更清晰。是否有适当的“功能”方式来执行这种类型的“if/else”短路 def getSingleProduct(firstSku: String): Option[Product] =

我有一组按顺序完成的操作,但如果中间序列返回“null”,我希望提前中止操作(跳过后续步骤)

我想出了一个类似这样的函数,它给定一个输入参数,对Redis执行若干操作,并将返回一个存在的产品。因为有可能其中一个中间请求返回空值,所以整个操作可能会“失败”,我想缩短后面不必要的步骤

这里的筑巢越来越疯狂,我想让它更清晰。是否有适当的“功能”方式来执行这种类型的
“if/else”
短路

def getSingleProduct(firstSku: String): Option[Product] = {
    val jedis = pool.getResource
    val sid: Array[Byte] = jedis.get(Keys.sidForSku(firstSku, sectionId, feedId).getBytes)
    Option(sid).flatMap {
      sid: Array[Byte] =>
        Option(jedis.get(Keys.latestVersionForSid(sectionId, feedId, sid))) flatMap {
          version: Array[Byte] =>
            Option(Keys.dataForSid(sectionId, feedId, version, sid)) flatMap {
              getDataKey: Array[Byte] =>
                Option(jedis.get(getDataKey)) flatMap {
                  packedData: Array[Byte] =>
                    val data = doSomeStuffWith(packedData)
                    Option(Product(data, "more interesting things"))
                }
            }
        }
    }
  }

执行此操作的方法是使用
for

for {
  sid <- Option(jedis.get(...))
  version <- Option(jedis.get(..., sid, ...))
  getDataKey <- Option(jedis.get(...version,...))
  packedData <- Option(jedis.get(getDataKey))
} yield {
  // Do stuff with packedData
}
用于{
希德