Search code examples
scala

How to define an identity function using placeholders in Scala?


I'm trying to express the identity function in a lambda expression using placeholders, writing (_) instead of (x => x). However, it doesn't give me the result I want:

scala> :t (1 to 5).map(_ + 1)
IndexedSeq[Int]
                                                                                                                      
scala> :t (1 to 5).map(_)
(Int => Any) => IndexedSeq[Any]

What makes the second lambda different (in terms of typing) from the first one? Isn't it just syntactic sugar that should be replaced with x => x?


Solution

  • Scala's rules for how far an underscore goes can be a bit complicated. But suffice to say, a lone underscore does not denote a function.

    (1 to 5).map(_ + 1)
    

    This is not a lone underscore. It's _ with the function .+(1) being applied, so it's equivalent to

    (1 to 5).map( x => x + 1)
    

    On the other hand,

    (1 to 5).map(_)
    

    Here, the whole call actually gets absorbed into the underscore syntax, so the argument goes to the very front.

    x => (1 to 5).map(x)
    

    which is not what you intended. As indicated in the comments, the underscore syntax is for very specific use cases, and if it's in the slightest bit ambiguous what you meant (and it certainly is here), you should write an explicit lambda.

    (1 to 5).map(x => x)
    

    or just use the built-in function.

    (1 to 5).map(identity)