【问题标题】:Scala - Nested loops, for-comprehension and type of the final iterationScala - 嵌套循环、理解和最终迭代的类型
【发布时间】:2012-02-06 14:47:24
【问题描述】:

我对 scala 比较陌生,并且成功地制作了一些非常简单的程序。 然而,现在我正在尝试一些现实世界的问题解决方案,事情变得有点困难......

我想将一些文件读入“配置”对象,使用可以“接受”某些文件(每个 FileTypeReader 子类型一个)的各种“FileTypeReader”子类型,如果它可以从中提取配置,则返回一个 Option[Configuration] .

我试图避免命令式风格,并写了类似这样的东西(使用 scala-io,scaladoc for Path here http://jesseeichar.github.com/scala-io-doc/0.3.0/api/index.html#scalax.file.Path):

(...)
trait FileTypeReader {
   import scalax.file.Path
   def accept(aPath : Path) : Option[Configuration]
}
var readers : List[FileTypeReader] = ...// list of concrete readers
var configurations = for (
          nextPath <- Path(someFolder).children();
          reader <- readers
      ) yield reader.accept(nextPath);
(...)

当然,这不起作用,for-comprehensions 返回第一个生成器类型的集合(这里是一些 IterablePathSet)。

由于我尝试了许多变体并且感觉像在循环中运行,所以我请求您就这件事提出建议以解决我的 - 琐碎问题? - 优雅的问题! :)

非常感谢,

sni.

【问题讨论】:

  • 这有点困难,除非你告诉我们理解中元素的类型是什么——即children() 返回什么,readers 是什么。 REPL 示例对于提出 scala 问题非常有用,因为它们可以被 REPLicated
  • 我把我的问题编辑得更清楚了!

标签: scala loops


【解决方案1】:

如果我理解正确,您的问题是您有一个Set[Path] 并且想要产生一个List[Option[Configuration]]。如所写,configurations 将是Set[Option[Configuration]]。要将其更改为 List,请使用 toList 方法,即

val configurations = (for {
    nextPath <- Path(someFolder).children
    reader   <- readers
  } yield reader.accept(nextPath) ).toList

或者,改变生成器本身的类型:

val configurations = for {
    nextPath <- Path(someFolder).children.toList
    reader   <- readers
  } yield reader.accept(nextPath)

你可能真的想得到一个List[Configuration],你可以优雅地做到这一点,因为Option是一个monad:

val configurations = for {
    nextPath <- Path(someFolder).children.toList
    reader   <- readers
    conf     <- reader.accept(nextPath)
  } yield conf

【讨论】:

  • 嗯,Luigi,这太棒了,正是我想要的!但是,任何人都可以解释我为什么得到:“ScalaObject => scala.collection.TraversableOnce[B] 没有可用的隐式视图”,当我在没有 toList 的情况下使用第一个解决方案尝试“configurations.flatten”时,为什么它工作得很好当我添加它?
  • 我不知道;它应该可以工作(Set(Some(1), None).flatten 编译)。您没有使用 2.8 之前的 Scala 的古老版本,是吗?见stackoverflow.com/questions/2895069/…
  • 不,2.9.1 和 sbt 0.11.2 和 scala.io 0.3.0
【解决方案2】:

您是否试图找到它可以提取的 first 配置?如果不是,返回多个配置会怎样?

在第一种情况下,我只需要获取理解的结果并对其调用find,这将返回一个Option

【讨论】:

  • 你好丹尼尔,不,我想要一个可迭代的所有配置(因此我的变量名)!
猜你喜欢
  • 2014-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多