Syntax sugar and anonymous functions in Scala
Common expansions of syntax sugars and anonymous functions
Constructors and Functions as a first class citizen
We know scala is a functional programming language, and it is designed by mathematician. According to wiki, Apply is applying a function to its arguments. In Java, you would commonly expect:
Tree t = new Tree(args)
But in Scala, a Tree(args)
is actually Tree.apply(args)
so apply
method in Scala is the method you should override when you want to provide your functions as an object
object Tree {
def apply[A](aseq: A*): Tree[A] = {
... // saved for brevity
}
}
- reference on stackoverflow
- Quote from the above link:
apply
serves the purpose of closing the gap between Object-Oriented and Functional paradigms in Scala
How to use underscores
// ERROR: missing parameter type for expanded function
myStrings.foreach(println(_.toString))
it expands to:
myStrings.foreach(println(_ => _.toString))
it annoys the compiler because compiler does not know the type of _
- reference on stackoverflow
- Quote from it:
The placeholder syntax for anonymous functions replaces
the smallest
possible containing expression with a function.
Pass Seq or List to vararg functions
There is a very example of when we need the varargs instead of Seq. A container is holding a type A
, and its members are expecting type A as well:
class ContainerClass[+A] {
def apply(aSeq: A*): ContainerClass[A] = ...
}
If we pass the seq to the apply
function, it will actually infer the A to be the type of Seq[A]
, so we need the A
, not the Seq[A]
. We can use this call:
ContainerClass.apply(aseq: _*)
The compiler will pass A
instead of Seq[A]
to the function
Good online Scala material
Pattern matching
In Scala, pattern matching is a function too. The compiler will create anonymous function for us. The compiler needs to be able to tell the type of the arguments in the function.
The nice quotes:
{ case X(x) => ... } is a partial function, but the compiler still doesn't know what your input type is, except that it's a supertype of X. Normally this isn't a problem because if you're writing an anonymous function, the type is known from the context.
And the error we should learn from:
{case QualifiedType(preds, ty) =>
t.ty = ty ;
Some((emptyEqualityConstraintSet,preds)) }