I would like to use some of functional-interfaces inside the java.util.function
package like DoubleBinaryOperator
interface.
I can use it in Java as below:
public enum Operation {
PLUS("+", Double::sum),
MINUS("-", (x, y) -> x - y),
TIMES("*", (x, y) -> x * y),
DIVIDE("/", (x, y) -> x / y);
private final String symbol;
private final DoubleBinaryOperator op;
Operation(String symbol, DoubleBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
}
But it doesn't work for me in Kotlin because Kotlin cannot infer the type of the parameter.
enum class Operation private constructor(private val symbol: String, private val op: DoubleBinaryOperator) {
PLUS("+", { x, y -> x + y }),
MINUS("-", { x, y -> x - y }),
TIMES("*", { x, y -> x * y }),
DIVIDE("/", { x, y -> x / y });
}
You can achieve what you want (SAM conversion) with the following syntax:
enum class Operation private constructor(private val symbol: String, private val op: DoubleBinaryOperator) {
PLUS("+", DoubleBinaryOperator { left, right -> left + right }),
...
}
Note that this works only to implement Java interfaces, as documented here.
To expand on my comment below, Kotlin lambdas can be used in place of functional interfaces (what is known as SAM conversion) only when calling Java code from Kotlin. This is not allowed in pure Kotlin as you can use function types (e.g., (Double, Double) -> Double
, to mimic DoubleBinaryOperator
).
As an example, consider the following Java class:
public class MyClass {
String append(String input, Supplier<String> supplier) {
return input.concat(supplier.get());
}
}
In Kotlin you can use it like this:
val myClass = MyClass()
// Use case 1
myClass.append("something") {
"suffix"
}
// Use case 2
myClass.append("Something", Supplier { "suffix" })
Note that my IDE tells me there's a "Redundant SAM-constructor" for use case 2.
Now, let's rewrite MyClass
in Kotlin:
class MyClass {
fun append(input: String, supplier: Supplier<String>): String {
return input + supplier.get()
}
}
If we don't change the code using it, we'll get a compilation error for use case 1: "Required Supplier, found () -> String" (that's the same issue you're getting) because SAM conversion cannot be done. However, you can "force" it by using SAM constructors (that is use case 2).