I have something that looks like this:
def a(b:String)(implicit c:String = "") = {println(b); b}
a("1")(a("2")(a("3")))
which prints
3
2
1
How can I get scala to print out this instead?
1
2
3
I have something that looks like this:
def a(b:String)(implicit c:String = "") = {println(b); b}
a("1")(a("2")(a("3")))
which prints
3
2
1
How can I get scala to print out this instead?
1
2
3
Laziness is always the way to go to invoke code not before it is used. In your example, though, you are not using c
at all, which would mean that when it is lazy it would never be invoked at all.
Changing this a little bit would result in:
scala> def a(b: String)(c: => String = "") = {println(b); c; b}
a: (b: String)(c: => String)String
scala> a("1")(a("2")(a("3")()))
1
2
3
res15: String = 1
Here, c
is declared as call-by-name, which results in the lazy behavior. However implicit parameters can't be call-by-name, thus we have to use a more heavyweight approach:
scala> import scala.language.implicitConversions
import scala.language.implicitConversions
scala> def a(b: String)(implicit c: () => String = () => "") = {println(b); c(); b}
a: (b: String)(implicit c: () => String)String
scala> implicit def conv(s: => String) = () => s
conv: (s: => String)() => String
scala> a("1")(a("2")(a("3")))
1
2
3
res0: String = 1
Now, the laziness is even more explicit but we need an implicit conversion to allow your original syntax.
In summary you can't just toggle the evaluating order of your function arguments, you have to understand laziness to benefit from it. Nevertheless laziness comes with syntactic overhead (at least in Scala, in Haskell for example it would already be built-in into the language), therefore it leads to a different design of your code.