I am creating a library and am exposing a class called A that has in it defined a function func(f: SomeType => A)
. It is imperative that func is called with the following syntax:
val x = new A()
val y = new A()
x.func(_ => y)
However in reality I want the body of func()
to perform logic based on the value of y. The function being passed as argument is not actually important.
I'm new to Scala and I have looked into using implicits and scala reflect with little joy. How can I go about doing this?
This looks like a much better question than the one from the other day :)
Let's discuss the type of _ => y
. If your contract is such that the user must provide a function, and in reality they should provide one which totally ignores the argument and produces y
, then you should probably make it Unit => A
. That way, func
body can just apply the received function to an empty value.
Let's say that A = Int
:
val f: Unit => Int = _ => 42
def func(f: Unit => Int) = {
f() // apply f to empty argument
}
func(f) // 42
The only point of creating such a thunk would be to achieve lazy evaluation of y
. Similar effect can be achieved by taking the call-by-name parameter (indicated by => Type
) instead of a function:
def func(f: => Int) = {
f
}
func(42) // 42
If you can't change the function type from SomeType => A
, then you can obtain y
by providing any kind of SomeType
. Even null
.
Let's say that SomeType = String
and A = Int
:
val f: String => Int = _ => 42
def func(f: String => Int) = {
f(null) // ugly but works
}
func(f) // 42
But keep in mind that this is extremely weird and misleading. If the function is not important, why is it being required? Someone could provide the following String => Int
function:
val f: String => Int = _.length
And what you're saying is, "I don't care about the input String". Well, how are you going to obtain the Int
then? If you decide to obtain the Int
by passing some String
value to f
, which value are you going to pass?
You would have to rely on the user of your library to always provide a function that doesn't care about the input argument, such as val f: String => Int = _ => 42
(as shown in an earlier example). Then you can obtain your Int
by providing whatever random dummy String
value, or even null, "knowing" (= hoping) that the provided function will ignore its argument.