Подтвердить что ты не робот

Scala для понимания выражений `if`

Можно ли в scala специализироваться на условиях внутри if внутри a для понимания? Я думаю по строкам:

val collection: SomeGenericCollection[Int] = ...

trait CollectionFilter
case object Even extends CollectionFilter
case object Odd extends CollectionFilter

val evenColl = for { i <- collection if(Even) } yield i
//evenColl would be a SomeGenericEvenCollection instance

val oddColl = for { i <- collection if(Odd) } yield i
//oddColl would be a SomeGenericOddCollection instance

Суть в том, что, уступая i, я получаю новую коллекцию потенциально другого типа (следовательно, я имею в виду ее как "специализацию" ) - в отличие от просто отфильтрованной версии того же типа GenericCollection.

Причина, по которой я спрашиваю, это то, что я увидел нечто, что я не мог понять (пример можно найти

4b9b3361

Ответ 1

Итак, я думаю, вы спрашиваете, возможно ли, чтобы оператор if в целях понимания изменил тип результата. Ответ "да, но...".

Во-первых, поймите, как расширяются знания. Здесь обсуждаются вопросы о переполнении стека, и есть параметры, которые вы можете передать компилятору, чтобы он показал вам, что происходит.

В любом случае, этот код:

val evenColl = for { i <- collection if(Even) } yield i

Переводится как:

val evenColl = collection.withFilter(i => Even).map(i => i)

Итак, если метод withFilter изменяет тип коллекции, он будет делать то, что вы хотите - в этом простом случае. В более сложных случаях это не будет работать:

for {
  x <- xs
  y <- ys
  if cond
} yield (x, y)

переводится как

xs.flatMap(ys.withFilter(y => cond).map(y => (x, y)))

В этом случае flatMap определяет, какой тип будет возвращен. Если он берет сигнал от того, какой результат был возвращен, он может работать.

Теперь, в Scala Collections, withFilter не изменяет тип коллекции. Вы могли бы написать свои собственные классы, которые могли бы это сделать, однако.

Ответ 2

да, вы можете - пожалуйста, обратитесь к этому учебнику для легкого примера. Пример запроса scala, который вы указали, также выполняет итерацию в коллекции, затем использует эти данные для построения запроса.