【问题标题】:Is there a way to declare an implicit val inside a for comprehension?有没有办法在 for 理解中声明一个隐式 val?
【发布时间】:2012-12-13 22:32:07
【问题描述】:

我有一些嵌套调用 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: 这应该适用于所有可用于 for 理解的类型,因此不仅适用于常见的集合类型,如 ListSeq,还适用于 Future .

【问题讨论】:

  • 我会接受功能请求...
  • 我将在 SI-2823 下试一试;在这个问题的时候,我看着它。如果您将隐式 f
  • @som-snytt:我不太清楚您所说的“将未来主义指定为必要条件”是什么意思。也许您可以自己编辑问题或提出编辑建议?
  • 我可以编辑它吗?仍然是一个新手。通过未来主义,我对您对另一个答案的旧评论感到很可爱,它必须与期货一起使用。
  • @som-snytt:如果您无法编辑它(由于声誉低下),您可以提出编辑建议,我可以改进它。我会编辑它,如果你觉得有必要,你可以添加。

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


【解决方案1】:

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

【讨论】:

  • 这个问题八周年了,耶
  • 仅供参考,自 Scala 3.0 起已修复
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    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)
    

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

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

    【讨论】:

      【解决方案4】:

      这段代码怎么样?

      // 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*
      

      【讨论】:

      • 除了是一个可怕的黑客之外,这也不适用于期货(不使 s 易变)或并行集合。
      • 谢谢,添加了 volatile。你喜欢一棵树吗?
      • +1 因为它看起来像几个季节前的 Scala 圣诞树。不知道我现在能不能找到链接,但我会尝试谷歌。
      • scala-lang.org/node/12024,一个简单的谷歌。它实际上并不像 scala 树,但可能会导致谜题。
      • 太酷了!我的是比萨的圣诞树,只落在左侧。假期最后一天的产物,这就是原因。
      猜你喜欢
      • 2015-11-05
      • 2010-12-22
      • 1970-01-01
      • 2018-04-04
      • 1970-01-01
      • 2011-02-09
      • 1970-01-01
      • 2012-07-01
      • 2014-11-19
      相关资源
      最近更新 更多