斯卡拉的理解`if`陈述

Dyl*_*lan 25 scala

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
Run Code Online (Sandbox Code Playgroud)

要点是通过屈服i,我得到一个可能不同类型的新集合(因此我将其称为"专业化") - 而不是仅仅是相同GenericCollection类型的过滤版本.

我问的原因是我看到了一些我无法弄清楚的东西(一个例子可以在这个ScalaQuery示例的第33行找到.它的作用是创建一个数据库查询(即SELECT ... FROM ... WHERE ...),我希望它在那里迭代所述查询的结果.

Dan*_*ral 50

所以,我认为你在询问iffor-comprehension中的语句是否有可能改变结果类型.答案是"是的,但是......".

首先,了解如何扩展理解.这里有关于Stack Overflow讨论它的问题,你可以将参数传递给编译器,这样它就会告诉你发生了什么.

无论如何,这段代码:

val evenColl = for { i <- collection if(Even) } yield i
Run Code Online (Sandbox Code Playgroud)

翻译为:

val evenColl = collection.withFilter(i => Even).map(i => i)
Run Code Online (Sandbox Code Playgroud)

因此,如果withFilter方法更改了集合类型,它将执行您想要的操作 - 在这种简单的情况下.在更复杂的案例中,仅此一点不起作用:

for {
  x <- xs
  y <- ys
  if cond
} yield (x, y)
Run Code Online (Sandbox Code Playgroud)

被翻译为

xs.flatMap(ys.withFilter(y => cond).map(y => (x, y)))
Run Code Online (Sandbox Code Playgroud)

在哪种情况下flatMap决定将返回什么类型.如果它从返回的结果中获取提示,那么它可以工作.

现在,在Scala Collections上,withFilter不会更改集合的类型.但是,您可以编写自己的类来执行此操作.