37

I have some code with nested calls to flatMap like so:

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

Normally, one would write that as a for comprehension, which makes the code a lot more readable:

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

But I need f to be implicit and I don't see a way to do that with for comprehensions. Is there? Of course I could pass f explicitly, but that would mean bye bye pretty DSL. I'd be interested in answers for both Scala 2.9 and 2.10.

Just to be clear, I would like to do something like this, but it won't compile:

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

EDIT: Maybe a feature request would be a good idea?

EDIT2: This should work with all types that can be used in a for comprehension, so not just with the usual collection types like List or Seq, but also with Future.

Kim Stebel
  • 41,826
  • 12
  • 125
  • 142
  • 1
    I would go with the feature request... – kiritsuku Dec 29 '12 at 14:58
  • I'm going to give this a shot under SI-2823; I looked at it, at the time of this question. There are other issues bearing on this encoding, if you see implicit f<-foo as f0<-foo;implicit f=f0. If you edit the question to specify Futurism as a requisite, I can upvote, too. – som-snytt Jun 04 '13 at 01:15
  • @som-snytt: I'm not quite sure what you mean by "specify Futurism as a requisite". Maybe you can edit the question yourself or suggest an edit? – Kim Stebel Jun 04 '13 at 09:10
  • Can I edit it? Still an SO newbie. By Futurism, I was being cute about your old comment on another answer that it must work with futures. – som-snytt Jun 04 '13 at 14:07
  • @som-snytt: If you can't edit it (due to low reputation), you can suggest an edit and I can improve it. I'll edit it and then you can add to that if you feel that's necessary. – Kim Stebel Jun 04 '13 at 15:34

4 Answers4

19

No, there isn't. There is a ticket though: https://issues.scala-lang.org/browse/SI-2823

Kim Stebel
  • 41,826
  • 12
  • 125
  • 142
12

Since version 0.3.0-M1, a better-monadic-for compiler plugin provides such functionality.

user2840658
  • 121
  • 1
  • 2
6

Scala 3 (Dotty) enables givens (implicits) in for-comprehensions, for example

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

According to Implicits in for comprehensions/pattern matches SIP tracking #6

Martin points out that it Dotty already supports the more ambitious version as long as the types are annotated. so e.g. in Dotty this compiles: implicit val (a: Int, b: String) = (3, "foo")

pme
  • 14,156
  • 3
  • 52
  • 95
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
0

How about this code?

// 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*
idonnie
  • 1,703
  • 12
  • 11
  • 2
    Apart from being a terrible hack, this also won't work with futures (without making s volatile) or with parallel collections. – Kim Stebel Jan 03 '13 at 00:02
  • Thank you, added volatile. Do you like a tree? – idonnie Jan 03 '13 at 00:17
  • 1
    +1 because it looks like the Scala Christmas tree from a few seasons back. Don't know if I can find the link now, but I'll try google. – som-snytt Jun 04 '13 at 01:09
  • 1
    http://www.scala-lang.org/node/12024, an easy google. It doesn't actually look like the scala tree, but maybe it will result in a puzzler. – som-snytt Jun 04 '13 at 01:16
  • How cool! Mine was a Christmas Tree of Pisa, falls only on the left side. Product of the last day of vacation, that's why. – idonnie Jun 05 '13 at 20:58