在for推导式中是否有一种方式声明隐式val?

37

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

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

通常我们会写成for comprehension的形式,这样代码就更易读了:

通常情况下,人们会使用for comprehension来编写代码,使得代码更易于阅读。

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

但是我需要f是隐式的,而且我不认为使用for comprehensions可以实现这一点。有方法可以实现吗?当然,我可以显式地传递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*/
}

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

编辑2: 这应该适用于所有可以在 for 推导式中使用的类型,因此不仅限于通常的集合类型,如 ListSeq,还包括 Future


1
我会选择支持这个功能请求... - kiritsuku
我将在SI-2823下尝试这个;我在提问时已经看过它了。如果您看到隐式f<-foo作为f0<-foo; 隐式f=f0的其他编码问题,请注意。如果您编辑问题以指定未来主义为必需,则我也可以点赞。 - som-snytt
@som-snytt:我不太确定你所说的“将未来主义作为必备条件”是什么意思。也许你可以自己编辑问题或提出修改建议? - Kim Stebel
我可以编辑吗?我还是一个 Stack Overflow 新手。在 Futurism 中,我对你在另一个答案中关于它必须与 futures 一起工作的旧评论感到有趣。 - som-snytt
@som-snytt:如果您由于声望不足而无法编辑它,您可以建议进行编辑,然后我可以改进它。我会进行编辑,然后如果您认为有必要,您可以添加内容。 - Kim Stebel
4个回答

19

14
这个问题已经迎来了它的第8个周年,耶! - Deliganli
2
FYI,自Scala 3.0以来,这个问题已经被修复。 - Joan

12

6
Scala 3 (Dotty) 在 for-comprehensions 中启用 givens(隐式参数),例如 example
Starting dotty REPL...
scala> for {
     |   given Int <- Some(41)
     |   y <- Some(1)
     | } yield summon[Int] + y
val res0: Option[Int] = Some(42)

根据 for comprehensions/pattern matches SIP tracking #6,Martin指出只要类型有注释,Dotty已经支持更为雄心勃勃的版本。因此,在Dotty中,以下代码可以编译:implicit val (a: Int, b: String) = (3, "foo")

1
给定 Int <- Some(41) 现在,没有名称,也没有 '_:' - 就像我现在看到的那样。 - Hunor Kovács

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*

2
除了这是一个可怕的黑客之外,如果不让s变成不稳定状态,它也无法与未来(futures)一起使用,也不能与并行集合一起使用。 - Kim Stebel
谢谢,已添加volatile。你喜欢树吗? - idonnie
1
+1 是因为它看起来像几个季节前的 Scala 圣诞树。现在不知道能否找到链接,但我会尝试谷歌搜索。 - som-snytt
1
http://www.scala-lang.org/node/12024,谷歌轻松搞定。它看起来并不像Scala Tree,但也许会造成困惑。 - som-snytt
太酷了!我的是比萨斜塔的圣诞树,只会倒在左边。那是假期的最后一天的产物。 - idonnie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接