So, reading the Scala tour about implicit classes in Scala, I came across this piece of code:
object Helpers {
implicit class IntWithTimes(x: Int) {
def times[A](f: => A): Unit = {
def loop(current: Int): Unit =
if(current > 0) {
f
loop(current - 1)
}
loop(x)
}
}
}
What is troubling me here is the def times[A](f: => A): Unit = {
line. What is going on here?
The part of the function type parameter, A
, I understand, but I cannot fully comprehend out what is the (f: => A)
part.
Is it denoting that f is a function which takes any kind / number of arguments, and return an object of type A?
Therefore, does this construction effectively mean a function which takes whatever parameters and return whatever I want?
Here is a chat on the topic from Scala gitter channel providing an excelent analogy for by-name parameters
Gavin Bisesi @Daenyth Feb 24 17:08
=> X
is "by-name" syntax It's syntax sugar for something that's very much like() => X
The caller doesn't need to supply the() =>
part, and referencing it in the method body also doesn't need()
but otherwise is basically the sameRob Norris @tpolecat Feb 24 17:17
...I think it's best to think of by-name arguments acting like
def
s and normal arguments acting likeval
s. Under the covers it's a nullary function but from the language's point of view it's different.def foo(a: => String)
anddef foo(a: () => String)
have different types and a behaves differently in the body of each foo.Fabio Labella @SystemFw Feb 24 20:19
@Daenyth re
def/val
:A /: => A
I actually start my tutorials on programs as values with that.def/: => A
is related to "being", vsval/: A
is related to "doing", and understanding the doing/being dichotomy is really useful to understanding FP with effects, and it also translates to pure FP paradigms that actually use native "doing" (unlike as what we do with programs as values, where everything is "being" and "doing" happens in a metalanguage of combinators such asflatMap
). An example would be algebraic effects in Unison