Скала для понимания `if` заявления - PullRequest
25 голосов
/ 31 октября 2011

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

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.

Причина, по которой я спрашиваю, заключается в том, что я увидел что-то, что не смог выяснить (пример можно найти в строке 33этот пример ScalaQuery . Он создает запрос к базе данных (т. е. SELECT ... FROM ... WHERE ...), где я ожидал бы, что он будет перебирать результаты этого запроса.

Ответы [ 2 ]

49 голосов
/ 31 октября 2011

Итак, я думаю, что вы спрашиваете, возможно ли для оператора 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 withFilter не меняет тип коллекции . Однако вы можете написать свои собственные классы, которые будут это делать.

5 голосов
/ 31 октября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...