функциональная скала - как избежать глубокого вложения на дополнительные отображения - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть набор операций, которые выполняются последовательно, но если промежуточная последовательность возвращает «ноль», я хотел бы прервать операцию раньше (пропустите последующие шаги).

Я создал такую ​​функцию, которая задала входной параметр, выполняет несколько операций с 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"))
                }
            }
        }
    }
  }

1 Ответ

0 голосов
/ 04 сентября 2018

Способ сделать это - использовать 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
}

Возвращается None, если любой из вызовов get возвращает None, в противном случае возвращается Some(x), где x - результат выражения yeild.

Возможно, вы захотите написать оболочку для jedis.get, которая возвращает Option(x) вместо использования null в качестве результата ошибки.

...