Search code examples
scalaanonymous-function

Scala Anonymous Function Defined as Composition of Two Functions


I am a beginner in Scala, and currently studying the fascinating concept of anonymous functions. However, my following attempt at defining one results in a compilation error:

def double(f:Int => Int): Int => Int = f(f(_))
println(double(_ * 2)(4))

[error]  found   : Int => Int
[error]  required: Int
[error]   def double(f: Int => Int): Int => Int = f(f(_))
[error]                                              ^

It seems that applying the function twice to the underscore doesn't work, but why?

The following functions are compiled successfully:

def double(f:Int => Int): Int => Int = x => f(f(x))
def apply(f:Int => Int): Int => Int = f(_)

I feel like the two implementations of double should be equivalent, since it replaces the argument x that is used only once in the body, but they are clearly different in the compiler's view.

I guess what I'm trying to ask is, why the first implementation of double fails while the second succeeds. Should the underscore be somehow 'directly' used in the function body? What would that mean exactly?


Solution

  • Double for example can look like (if you want anonymous function syntax):

    def double(f:Int => Int): Int => Int = f.andThen(f)(_) // or (f andThen f)(_)
    

    Or simply via function composition:

    def double(f:Int => Int): Int => Int = f andThen f
    

    f(_) will be expanded as x => f(x) so f(f(_)) is treated as f(x => f(x)).