Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I omit "apply" in this.apply(_) in Scala?

Tags:

types

scala

apply

Observe the following code

trait Example {
  type O
  def apply(o: O)
  def f(o: O) = this.apply(o)
}

which compiles fine in Scala. I would expect that I can leave out apply as usual, writing def f(o: O) = this(o). However, this results in the exciting error message

type mismatch;  found   : o.type (with underlying type Example.this.O)
                required: _31.O where val _31: Example
possible cause: missing arguments for method or constructor

Can anyone explain to me what's going on?

like image 883
Scott Morrison Avatar asked Dec 24 '11 20:12

Scott Morrison


People also ask

What is def apply in Scala?

The apply() method is utilized to select an element in the list by its index. Method Definition: def apply(n: Int): A. Return Type: It returns an element from the given list by its index which is present in the apply method as argument. Example #1: // Scala program of apply()

Is apply a constructor in Scala?

No. In Scala, the constructor is invoked using the new operator (just like in Java) and is named this (the primary constructor doesn't have a name at all, it is just the body of the class). apply and unapply aren't constructors, they are methods.

What is the significance of apply method?

The apply() method allows you to apply a function along one of the axis of the DataFrame, default 0, which is the index (row) axis.

How does Scala determine types when they are not specified?

For example, a type constructor does not directly specify a type of values. However, when a type constructor is applied to the correct type arguments, it yields a first-order type, which may be a value type. Non-value types are expressed indirectly in Scala.


2 Answers

You can't because this() inside an constructor is a call to this object's constructor (this() anywhere else generates a compilation failure) and can not be made into an apply() call as it would hide the constructor and make it impossible to call another constructor in your object. this(args) is always a call to a constructor method (both in Java and Scala), so when inside your own object, you always have to explicitly call apply(args).

like image 100
Maurício Linhares Avatar answered Nov 13 '22 00:11

Maurício Linhares


The accepted answer is incorrect. You can infer what the actual problem is from the fact that this compiles fine:

trait Example {
  def apply(o: String): String = o
  def f(o: String) = this(o)
}

this(...) only represents a call to a constructor when the call site is an auxiliary constructor. The remainder of the time it is a call to apply, just as you imagined.

like image 26
psp Avatar answered Nov 12 '22 23:11

psp