Scala中隐含的' for'枚举?

时间:2015-04-03 13:08:59

标签: scala implicit

如何在for语句中引入变量(枚举器,因为它在规范中调用)是隐式的?

以下是我喜欢写的一个例子:

for (implicit genNum: GenNum <- NumGens(200)) {
  val explicitArg = // . . .
  funcWithImplicitGenNum(explicitArg)  // <-- gen passed implicitly here
}

其中funcWithImplicitGenNum的声明如下:

def funcWithImplicitGenNum(explicitArg: Whatever)(implicit gen: GenNum) = ???

如果我正确理解规范,它不允许隐含for的枚举器,所以我必须这样做:

for (g <- NumGens(200)) {
  implicit val genNum: GenNum = g
  val explicitArg = // . . .
  funcWithImplicitGenNum(explicitArg)  // <-- gen passed implicitly here
}

这种解决方法不是世界末日,但它困扰着我。在我的实际程序中,我在整个地方隐式传递了几个变量,这些变量提供了发生某些事情的整体上下文。 Scala的含义非常精彩:它们大大减少了代码中的混乱程度,但是调用堆栈中的深层函数可以访问该上下文信息。唯一的例外是for循环:我必须做一个笨拙的技巧来定义一个等于枚举变量的val

有没有办法隐式传递genNum?或者,如果没有,您是否知道为什么我应该感到高兴for语句不允许其枚举器隐含的原因? (通常情况下,如果您了解语言功能的基本原理,您会更好地了解如何“熟悉语言”。)


如果它有帮助,这里有更多背景知识。我正在编写一种使用各种变异算子的遗传算法。变异操作符不应该知道它被调用的是哪一代。但我也在收集有关突变在不同世代中的表现的数据。数据收集代码 需要知道它是哪一代,还有其他一些东西。因此,我明确地传递了与变异相关的变量,并隐式地传递了数据收集所需的变量。

2 个答案:

答案 0 :(得分:4)

目前无法实现。 Here是相关功能请求的票证。在那里,马丁奥德斯基写道:

  

我看到的问题是与许多其他事物的互动。 [隐含变量]   可能是一种模式 - 如果隐含然后适用于它的所有模式   变量?然后,for表达式中的生成器的转换是   非常介入。我们必须指明如何使用含义   帐户。

作为一种变通方法,您可以将implicit循环放在包裹mapflatMap中(当然,这不是理想的):

class Foo

object FooRunner {
    val foos = List(new Foo, new Foo, new Foo)
    def runFoo(i: Int)(implicit foo: Foo) = println(s"Foo ran $i")

    def runFoos = foos.map { implicit foo =>
        for(i <- (1 to 100)) {
            runFoo(i) //implicit works here.
        }
    }
}

答案 1 :(得分:1)

您可以像这样明确地传递隐式参数:

for (val genNum <- NumGens(200)) {
  val explicitArg = // . . .
  funcWithImplicitGenNum(explicitArg)(genNum)  // <-- gen passed explictly here
}

至于为什么问题,我没有证据,但考虑范围含义,这会说你在一个隐式for循环中使用val i而另一个程序员在另一个文件中试图做一个简单的for for loop with variable name。 巫毒会随之而来

虽然我实际上会映射(或foreach取决于功能副作用)

val result = NumGens(200).map{ implicit i =>
val explicitArg = ??
funcWithImplicitGenNum(explicitArg)
}