So let's say I want to create a custom function type called ImportFunc that takes in an Int called fileImportID and a string called filename. I can do this pretty easily using a type alias like so:
type ImportFunc = (Int, String) => Unit
The problem is, anybody trying to use this function has no idea what Int and String are actually supposed to be. Is there some way I can write something like:
type ImportFunc = (fileImportID: Int, filename: String) => Unit
A simple "type" solution:
I'm not too fond of Int and String as they are to easy to mix up with other Strings and Ints. Do:
In Scala, functions are defined from traits
FunctionX
, so you can do as following:When you call a function, you actually call the function's apply method. In other words, given this:
The following snippet:
...is just syntactic sugar for:
If there is a place where the compiler will look for the arguments's names when doing a call with named parameters, that's necessarily in the
apply
method's definition. It turns out that inFunction2
, those arguments are namedv1
andv2
. So we can do:Now let's see if it still works when using the syntactic sugar (in other words when removing the explicit call to
apply
):Nice, it works. Now of course
v1
andv2
is not quite the same asfileImportID
andfilename
, but we can fix that with a bit of type refinement:Basically this is just
(Int, String)=>Unit
(or in other wordsFunction2[Int, String, Unit]
) but with a redefinition ofapply
with our desired argument names. Let's see this in action:Success!
An important side note: in terms of typing,
ImportFunc
is identical toFunction2[Int, String, Unit]
, or to any other similar refinement. This is because argument names are not part of the signature. So in my examplef
can still be passed anywhere aFunction2[Int, String, Unit]
is expected (but from that point you won't be able anymore to call it using your custom argument names).