user1054583
user1054583

Reputation: 95

some operator questions

I'm new to scala so sorry if this is easy but I've had a hard time finding the answer.

I'm having a hard time understanding what <- does, and what ()=> Unit does. My understanding of these is that -> is sometimes used in foreach, and that => is used in maps. Trying to google "scala "<-" doesn't prove very fruitful. I found http://jim-mcbeath.blogspot.com/2008/12/scala-operator-cheat-sheet.html but it wasn't as helpful as it looks at first glance.

val numbers = List("one", "two", "three","four","five")
def operateOnList() {
  for(number <- numbers) {
    println(number + ": came out of this crazy thing!")
  }
}

def tweener(method: () => Unit) {
  method()
}

tweener(operateOnList)

Upvotes: 2

Views: 164

Answers (3)

Luigi Plinge
Luigi Plinge

Reputation: 51109

In the method

def tweener(method: () => Unit) {
  method()
}

the method is called tweener, the parameter is arbitrarily named method, and the type of method is () => Unit, which is a function type, as you can tell from the =>.

Unit is a return type similar to void in Java, and represents no interesting value being returned. For instance, the return type of print is Unit. () represents an empty parameter list.

Confusingly, () is also used to represent an instance of Unit, called the unit value, the only value a Unit can take. But this is not what it means in the function type () => Unit, just as you can't have a function type 42 => Unit.

Back to your example, tweener takes a function of type () => Unit. operateOnList is a method, but it gets partially applied by the compiler to turn it into a function value. You can turn methods into functions yourself like this:

scala> def m = println("hi")
m: Unit

scala> m _
res17: () => Unit = <function0>

operateOnList can be turned into the right type of function because its parameter list is empty (), and its return type is implicity Unit.

As a side-note, if operateOnList were defined without the empty parameter list (as is legal, but more common when the return type is not Unit), you would need to manually partially apply it, else its value will be passed instead:

def f1() {}
def f2 {}
def g(f: () => Unit) {}
g(f1)   // OK
g(f2)   // error, since we're passing f2's result (), 
        //   rather than partial function () => Unit
g(f2 _) // OK

Upvotes: 3

David
David

Reputation: 2399

() => Unit means that method is a function that takes no parameter and returns nothing (Unit).

<- is used in the for comprehension as an kind of assignation operator. for comprehension are a little bit specific because they are internally transformed. In your case, that would be transforms as numbers.foreach(i => println(i + ": came out of this crazy thing!"))

<- in the for comprehension means that we will iterate over each element of the numbers list and passed to number.

Upvotes: 5

om-nom-nom
om-nom-nom

Reputation: 62835

'<-' could be threated as 'in' so

for(number <- numbers){
...
}

could be translated into english as for each number in numbers do

'<-' has a twin with a different semantics: '->'. Simply it is just a replacement of comma in tuples: (a,b) is an equivalent to (a->b) or just a->b. The meaning after this symbols is that 'a' maps to 'b'. So this is often used in definition of Maps:

 Map("a" -> 1,"aba" -> 3)
 Map("London" -> "Britain", "Paris" -> "France")

Here you can think about mapping as a projection (or not) via some function (e.g. 'length of string', 'capital of').

Better explanation is here.

Last, but not least is '=>' which is map too, but with a general semantics. '=>' is in use all over the place in anonymous expressions:

scala> List(1,2,3,4).map(current => current+1)
res5: List[Int] = List(2, 3, 4, 5)

Which is for each element map current element of list with function 'plus one'

List(1,2,3,4).map(c => c%2 match {
     | case 0 => "even"
     | case 1 => "odd"
     | }
     | )
res6: List[java.lang.String] = List(odd, even, odd, even)

Map current element with provided pattern mathing

Upvotes: 4

Related Questions