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.

5
  • 1
    I would go with the feature request...
    – kiritsuku
    Dec 29, 2012 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 4, 2013 at 1: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 4, 2013 at 9: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 4, 2013 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 4, 2013 at 15:34

4 Answers 4

19

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

2
  • 14
    8th year anniversary for this issue, yay
    – Deliganli
    Sep 5, 2017 at 13:27
  • 2
    FYI This is fixed since Scala 3.0
    – Joan
    Jul 23, 2021 at 20:21
13

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

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")

1
  • 1
    given Int <- Some(41) now, no name, no _: - as i see now Jun 14, 2022 at 23:23
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*
5
  • 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 3, 2013 at 0:02
  • Thank you, added volatile. Do you like a tree?
    – idonnie
    Jan 3, 2013 at 0: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 4, 2013 at 1:09
  • 1
    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 4, 2013 at 1: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 5, 2013 at 20:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.