Question

I am trying to pass a function as a parameter, but that function has multiple arguments (one of which is a function).

Here is what I am trying to do in a basic Python example:

def first(string1, string2, func):
    func(string1, string2, third)

def second(string1, string2, func):
    func(string1, string2)

def third(string1, string):
    # operations go here

first("one", "two", second)

My attempt at this in Scala was the following:

def first(string1: String, string2: String, func: (Any, Any, Any) => Unit) = {
    func(string1, string2, func)
}
def second(string1: String, string2: String, func: (Any, Any) => Unit) = {
    func(string1, string2)
}

def third(string1: String, string2: String) = {
    // operations
}

def main(args: Array[String]): Unit = {
    first("one", "two", second)
}

I get an error for trying to pass second into first with an insufficient amount of arguments. Is it possible to achieve this functionality in the same style as the Python example?

EDIT:

I tried replacing the body of my main method with first("one", "two", second _) and it gives me a type mismatch error

type mismatch; found : (String, String, (Any, Any, Any) => Unit) => Unit required: (Any, Any, Any) => Unit

Any idea what's going on here?

Was it helpful?

Solution

What you are trying to do is not type-safe. You cannot assign (String, String, (Any, Any) => Unit) => Unit to (Any, Any, Any) => Unit. If you could, then you could do the following:

val f = second _
val af: (Any, Any, Any) => Unit = f
af(1, "abc", 5)

You can do it if you specify the types more precisely:

def second(string1: String, string2: String, func: (String, String) => Unit) = {
    func(string1, string2)
}

def third(string1: String, string2: String) = {
    // operations
}

def first(string1: String, string2: String, func: (String, String, (String, String) => Unit) => Unit) = {
    func(string1, string2, third)
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top