case class used as a function - why additional constructor/apply is not applicable?

42 views
Skip to first unread message

vatel

unread,
Oct 3, 2013, 12:28:41 PM10/3/13
to scala...@googlegroups.com
Hello,

I have noticed (par hasard!) that a case-class' name can be used as a
function. For example:

case class CallInfo(param: Int)

def extract[T](extractor: Int => T) = println(extractor(5))

// can be called like this - will print "CallInfo(5)"
extract(CallInfo)

But this last call does not work (not compiled) for any of these cases:

case class CallInfo(param: Long) {
def this(i: Int) = this(0L)
}

case class CallInfo(param: Long)
object CallInfo {
def apply(i: Int) = new CallInfo(0L)
}

I assumed that the compiler needed just an appropriate "apply" method,
and it's there in the generated bytecode (for the 1st and the last
examples). Could somebody explain this please?

--
Vatel

vatel

unread,
Oct 3, 2013, 12:35:12 PM10/3/13
to scala...@googlegroups.com
Seems I see the formal reason in the generated bytecodes:

public final class CallInfo$
implements Serializable

public final class CallInfo$ extends AbstractFunction1<Object, CallInfo>
implements Serializable

But why does not compiler generate "extends AbstractFunction1" for all
the cases I mentioned.

Also, if we stay at Scala level (before generating the bytecode), it is
usually enough to have "apply" method to become a function.

Thanks.
--
Vatel

Jason Zaugg

unread,
Oct 3, 2013, 12:39:52 PM10/3/13
to vatel, scala-user
The companion object of a case class extends FunctionN[ArgTypes..., CaseClass] if and only if:
  - you didn't write the companion object yourself (the compiler isn't willing to change the list of parents classes for such a manually written companion)
 - the case class doesn't take type parameters.

This is done largely for historical reasons with very early versions of Scala that had a different mechanism for the factory methods.

In all cases, you can convert the `apply` method to a function with:

   val function = CallInfo.apply _

or
   val function = CallInfo(_)

-jason




--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

vatel

unread,
Oct 3, 2013, 12:59:01 PM10/3/13
to scala...@googlegroups.com
Thanks Jason!

I did not think about partial application in this context...

--
Vatel
Reply all
Reply to author
Forward
0 new messages