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:これは、 for 内包表記で使用できるすべての型で機能するはずです。そのため、ListorSeqのような通常のコレクション型だけでなく、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 内包表記での指定 (暗黙)が有効になります。たとえば、

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

内包表記/パターン一致の Implicits によると、 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 に答える