Функциональный синтаксис для вложенных ifs - PullRequest
2 голосов
/ 23 августа 2011

иногда я пишу код, подобный следующему:

val item1 = list.find(_.source.name.equals("foo"))
if (item1.isDefined) doSomething1(item1)
else {
  val item2 = list.find(_.dest.name.equals("bar"))
  if (item2.isDefined) doSomething2(item2)
  else doSomethingElse()
}

У кого-нибудь есть более приятный синтаксис Scala для выкладывания этого кода?

Ответы [ 3 ]

6 голосов
/ 23 августа 2011

Я бы написал это как

list.find(_.source.name =="foo").fold(doSomething1) {
  list.find(_.dest.name == "bar").fold(doSomething2)(doSomethingElse)
}

но это потому, что я добавил метод fold к Option примерно так:

class FoldableOption[A](o: Option[A]) {
  def fold[Z](f: A => Z)(g: => Z) = o.map(f).getOrElse(g)
}
implicit def option_has_folds[A](o: Option[A]) = new FoldableOption(o)

Если вы не хотите добавлять метод fold, вы также можете использовать пару map, getOrElse:

list.find(_.source.name == "foo").map(doSomething1).getOrElse {
  list.find(_.dest.name == "bar").map(doSomething2).getOrElse(doSomethingElse)
}

что не намного более многословно.

2 голосов
/ 23 августа 2011

Наряду с тем, что сказал Кевин, лучше, если это выражения, которые что-то возвращают.Я собираюсь сделать то же самое, что и вы, но с другим конкретным примером:

val list = List(1,2,3,4)
val result = list.find(_ == 1).map(
  _ => "Found1").orElse(list.find(_ == 5).map(
    _ => "Found2")).getOrElse("Found3")

Однако ваш может выглядеть лучше :) Но избегайте побочных эффектов.Пусть цепочка if / else, или цепочка монад, будет выражением, которое оценивает что-то, а не какую-то странную вещь с побочными эффектами.

0 голосов
/ 23 августа 2011

Это должно работать, хотя будет немного медленнее:

val item1 = list find (_.source.name == "foo")
val item2 = list find (_.dest.name == "bar")
item1 map (doSomething1) orElse {
  item2 map (doSomething2)
} getOrElse doSomethingElse()

ОБНОВЛЕНИЕ: более эффективно, но не настолько аккуратно:

val item1 = list find (_.source.name == "foo")
item1 map (doSomething1) orElse {
  val item2 = list find (_.dest.name == "bar")
  item2 map (doSomething2)
} getOrElse doSomethingElse()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...