Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can anyone explain how the symbol "=>" is used in Scala

Tags:

scala

I've read a lot of code snippets in scala that make use of the symbol =>, but I've never really been able to comprehend it. I've tried to search in the internet, but couldn't find anything comprehensive. Any pointers/explanation about how the symbol is/can be used will be really helpful.

(More specifially, I also want to know how the operator comes into picture in function literals)

like image 405
Raj Avatar asked Sep 21 '12 11:09

Raj


People also ask

What does this symbol => Do in Scala?

Show activity on this post. => is the "function arrow". It is used both in function type signatures as well as anonymous function terms. () => Unit is a shorthand for Function0[Unit] , which is the type of functions which take no arguments and return nothing useful (like void in other languages).

What does arrow mean in Scala?

Arrow is a type class for modeling composable relationships between two types. One example of such a composable relationship is function A => B ; other examples include cats. data. Kleisli (wrapping an A => F[B] , also known as ReaderT ), and cats.

What is symbol literal in Scala?

Symbol literals A symbol literal 'x is a shorthand for the expression scala. Symbol("x") . Symbol is a case class, which is defined as follows. package scala final case class Symbol private (name: String) { override def toString: String = "'" + name }

What does :+ mean in Scala?

On Scala Collections there is usually :+ and +: . Both add an element to the collection. :+ appends +: prepends. A good reminder is, : is where the Collection goes. There is as well colA ++: colB to concat collections, where the : side collection determines the resulting type.


1 Answers

More than passing values/names, => is used to define a function literal, which is an alternate syntax used to define a function.

Example time. Let's say you have a function that takes in another function. The collections are full of them, but we'll pick filter. filter, when used on a collection (like a List), will take out any element that causes the function you provide to return false.

val people = List("Bill Nye", "Mister Rogers", "Mohandas Karamchand Gandhi", "Jesus", "Superman", "The newspaper guy")
// Let's only grab people who have short names (less than 10 characters)
val shortNamedPeople = people.filter(<a function>)

We could pass in an actual function from somewhere else (def isShortName(name: String): Boolean, perhaps), but it would be nicer to just place it right there. Alas, we can, with function literals.

val shortNamedPeople = people.filter( name => name.length < 10 )

What we did here is create a function that takes in a String (since people is of type List[String]), and returns a Boolean. Pretty cool, right?

This syntax is used in many contexts. Let's say you want to write a function that takes in another function. This other function should take in a String, and return an Int.

def myFunction(f: String => Int): Int = {
  val myString = "Hello!"
  f(myString)
}
// And let's use it. First way:
def anotherFunction(a: String): Int = {
  a.length
}
myFunction(anotherFunction)
// Second way:
myFunction((a: String) => a.length)

That's what function literals are. Going back to by-name and by-value, there's a trick where you can force a parameter to not be evaluated until you want to. The classic example:

def logger(message: String) = {
  if(loggingActivated) println(message)
}

This looks alright, but message is actually evaluated when logger is called. What if message takes a while to evaluate? For example, logger(veryLongProcess()), where veryLongProcess() returns a String. Whoops? Not really. We can use our knowledge about function literals to force veryLongProcess() not to be called until it is actually needed.

def logger(message: => String) = {
  if(loggingActivated) println(message)
}
logger(veryLongProcess()) // Fixed!

logger is now taking in a function that takes no parameters (hence the naked => on the left side). You can still use it as before, but now, message is only evaluated when it's used (in the println).

like image 109
Andrew Conner Avatar answered Sep 22 '22 07:09

Andrew Conner