2
votes

I'm trying to write a simple function that will swap a (Int, String) tuple in Scala. I've tried a number of things and I keep getting compiler errors, for example:

def swap (p:(Int,String)) : (String,Int) = {
      var s = p._1
      var t = p._2
      var u = (p._2, p.1)
}

[error]  found   : Unit
[error]  required: (String, Int)
[error]     }
[error]     ^
[error] one error found

Why does it keep saying it finds a "Unit" type? I've tried different variations, and even using the "swap" function built into Scala, but I keep getting these kinds of errors stating that my return type isn't (String, Int). Any suggestions are appreciated. Thank you!

3
Your code has 2 problems: a missing underscore _ and you have 3 assignments but you don't return any values.jwvh
Woops on the underscore, I wasn't running it like that, I just put that in here as my example. Regarding the return - I thought Scala it would return what my last assignment is?Polyphase29
Yes, that's the problem: the last expression in your method is an assignment, and an assignment has no value, so that is what is being returned: a value that denotes the absence of a value.Jörg W Mittag

3 Answers

4
votes

The return value of a method (or more generally, the value of any block) is the value of the last expression inside the block. The last expression in your block is

var u = (p._2, p.1)

The value of an assignment is () (which is the singleton value of the Unit type): an assignment is a side-effect, it doesn't have a value, and () is the value (and Unit the type) which denotes the absence of a value (think "void" if you are familiar with C, C++, D, Objective-C, Objective-C++, Java, or C♯); ergo, your method returns (), which is of type Unit.

Here's a more Scala-ish way to write your method:

def swap[A, B](p: (A, B)) = (p._2, p._1)
1
votes

All you need is this:

def swap(p: (Int,String)): (String,Int) = (p._2, p._1)

And to make it work on any tuple (of size 2):

def swap[A,B](p: (A,B)): (B,A) = (p._2, p._1)

In Scala, the last expression in a function is the returned value. It also supports an explicit return expression, that would be like this:

def swap(p: (Int,String)): (String,Int) = { 
  return (p._2, p._1)
}

or more like what you intended:

def swap(p: (Int,String)): (String,Int) = { 
  val result = (p._2, p._1)
  return result
}

Keep in mind this explicit return syntax is not recommended.

Because Scala is a functional language, everything is an expression. Expressions are anything you can evaluate and get back a resulting value, which, being a value, has a type.

Even things that you would think more like "statements", like println("a") or var a = 1 are expressions. When evaluated, they return a meaningless/empty value, that is of type Unit. Therefore, your function returns the last statement, that is a variable assignment, which has a value of type Unit.

0
votes

You can also achieve it using pattern matching and function literal:

def swap[X,Y]: ((X,Y)) => ((Y,X)) = { case (x, y) => (y, x) }