1

I am new to Scala language and I was trying to define a basic function that flips its arguments, I defined it like this:

var flipArguments = ((a: Any, b: Any) => Any ) => ((b: Any, a: Any) => Any)

but I am getting a compiling error that highlights the second arrow with the message

';' or newline expected

and I am not understanding where I am making a syntax error.

Mario Galic
  • 47,285
  • 6
  • 56
  • 98
user156441
  • 175
  • 1
  • 6
  • 5
    First you are mixing the type definition with the function body. Second, please do not use `var` for a function. Third, in this case it would be better to write a **method**, as it can be _generic_ instead of using `Any`. Finally, here is the code you want: `def flip[A, B](a: A, b: B): (B, A) = (b, a)`. – Luis Miguel Mejía Suárez Jul 01 '19 at 13:58

2 Answers2

5

It depends on what you mean by flip.

Flip as in "change the value of two variables"

If you mean that

var a = 1
var b = 2
flip(a, b)

should result in a being 2 and b being 1, as one could do with references in C++, then this is not possible in Scala. Here is an explanation.

Flip as in "return a tuple of the arguments in reversed order"

This is already answered perfectly in Pedro's post. If this is what you want, you probably should use generics though, as mentioned by Luis in the comments.

Flip as in "turn a functions arguments around"

Given the signature you tried to write, your attempt looks to me as if you were trying to write a function which gets a function f and returns a new function, same as f, but with reversed argument order.

You can write such a function like this:

def flipAny(f: (Any, Any) => Any): (Any, Any) => Any =
  (a, b) => f(b, a)

and then call it on a function like this:

def stringify(a: Any, b: Any): String =
  s"a: ${a.toString}, b: ${b.toString}"

println(stringify(1,2))           // prints a: 1, b: 2
println(flipAny(stringify)(1,2))  // prints a: 2, b: 1

We can do better however, because using Any everywhere removes valuable type information.

What happens if we try to use the string result of stringify?

println(stringify(1,2).length)            // prints 10
//println(flipAny(stringify)(1,2).length) // doesn't compile

The second line doesn't compile because flipAny returns a function returning Any, not String.

Here is another definition using generics:

def flip[A, B, C](f: (A, B) => C): (B, A) => C =
  (a, b) => f(b, a)

This is much better. We are getting a function from A and B to C and returning a function from B and A to C. This retains the type information:

println(stringify(1,2))              // prints a: 1, b: 2
println(flip(stringify)(1,2))        // prints a: 2, b: 1
println(stringify(1,2).length)       // prints 10
println(flip(stringify)(1,2).length) // prints 10
felher
  • 81
  • 3
1

Maybe you want something like this:

def flipArguments(a:Any, b: Any): Any = (b, a)
Krzysztof Atłasik
  • 21,985
  • 6
  • 54
  • 76
Pedro Correia Luís
  • 1,085
  • 6
  • 16