35

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

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

通常,人们会将其写为 for 理解,这使代码更具可读性:

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:这应该适用于可用于理解的所有类型,因此不仅适用于通常的集合类型,如Listor Seq,而且适用于Future.

4

4 回答 4

16

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

于 2013-01-05T04:56:29.780 回答
11

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

于 2019-04-15T09:53:08.113 回答
3

Scala 3 (Dotty)在 for-comprehensions 中启用给定(隐含)例如

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

根据理解/模式匹配中的隐含 SIP 跟踪 #6

Martin 指出,只要类型被注释,它 Dotty 已经支持更雄心勃勃的版本。所以例如在 Dotty 中编译:implicit val (a: Int, b: String) = (3, "foo")

于 2020-09-13T13:04:46.623 回答
0

这段代码怎么样?

// 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*
于 2013-01-02T23:41:19.007 回答