有没有办法在for comprehension中声明一个隐含的val?

时间:2012-12-28 17:21:49

标签: scala implicit scala-2.10 scala-2.9 for-comprehension

我有一些代码嵌套调用flatMap,如下所示:

foo.flatMap(implicit f => bar(123).flatMap(b =>
  /* and so on... implicit f is still in scope here.*/
))

通常,人们会把它写成一个理解,这使得代码更具可读性:

for {
  f <- foo
  b <- bar(123)
  /* yet more method calls that need f as an implicit parameter*/
}

但是我需要f隐含,而我不会因为理解而看到这样做的方法。在那儿?当然我可以明确地传递f,但这意味着再见DSL。我对Scala 2.9和2.10的答案感兴趣。

为了清楚起见,我想做这样的事情,但它不会编译:

for {
  implicit f <- foo
  b <- bar(123) //bar takes implicit argument
  /* yet more method calls that need f as an implicit parameter*/
}

编辑:也许功能请求会是一个好主意?

EDIT2:这应该适用于所有可以用于理解的类型,因此不仅适用于ListSeq等常用的集合类型,而且与Future

4 个答案:

答案 0 :(得分:10)

不,没有#39; t。有一张票:https://issues.scala-lang.org/browse/SI-2823

答案 1 :(得分:1)

从0.3.0-M1版本开始,better-monadic-for编译器插件提供了这种功能。

答案 2 :(得分:1)

Scala 3(Dotty)为givens启用example(隐含)理解力

Starting dotty REPL...
scala> for {
     |   given _: Int <- Some(41)
     |   y <- Some(1)
     | } yield summon[Int] + y
val res0: Option[Int] = Some(42)

根据Implicits in for comprehensions/pattern matches SIP tracking #6

马丁指出,Dotty已经支持更雄心勃勃的 版本,只要注释了类型即可。所以在Dotty中 编译:{{1​​}}

答案 3 :(得分:-1)

这段代码怎么样?

// prerequisites
val (a,b) = (List(1,2,3), List(3,4,5,7,9))
def tree(n: Int)(implicit s: Int) = " "*s + "0"*n + (if (s+3 < n) "*" else "")

// actual for
@volatile implicit var s = 0
for (i <- a if ({s = i; true}); j <- b) 
  println(tree(j))

// 000
// 0000
// 00000*
// 0000000*
// 000000000*
//  000
//  0000
//  00000
//  0000000*
//  000000000*
//   000
//   0000
//   00000
//   0000000*
//   000000000*