Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do multiple, consecutive fat arrows in method parameters mean in Scala?

I understand that a method can have code like this:

def m(p1:Int => Int) ...

Which means this method takes a function p1 that returns an Int

But while browsing the Play! framework code i found a trait with indecipherable methods:

trait Secured {

  def username(request: RequestHeader) = request.session.get(Security.username)

  def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Auth.login)

  def withAuth(f: => String => Request[AnyContent] => Result) = {
    Security.Authenticated(username, onUnauthorized) { user =>
      Action(request => f(user)(request))
    }
  }

  /**
   * This method shows how you could wrap the withAuth method to also fetch your user
   * You will need to implement UserDAO.findOneByUsername
   */
  def withUser(f: User => Request[AnyContent] => Result) = withAuth { username => implicit request =>
    UserDAO.findOneByUsername(username).map { user =>
      f(user)(request)
    }.getOrElse(onUnauthorized(request))
  }
}

Play! Scala Security

What does the f: User => Request[AnyContent] => Result mean? At first glance it looks like a method that returns a function r of type Request; r then returns a Result.

Is this the right assumption?

like image 356
Cameron A. Ellis Avatar asked Dec 23 '12 17:12

Cameron A. Ellis


People also ask

Can arrow functions be nested?

The arrow functions are 3 levels nesting. It takes effort and time to understand what the code does. To increase readability of nested functions, the first approach is to introduce variables that each holds an arrow function.

What is double arrow function in Javascript?

An easy way to grasp this is to remember that a curried/double arrow function is a function that implicitly returns another function(s). Going by this logic, you could also have triple arrow functions and so on.


2 Answers

What does the f: User => Request[AnyContent] => Result mean? At first glance it looks like a method that returns a function r of type Request; r then returns a Result.

f returns a function of type Request[AnyContent] => Result, i.e. a function that takes a Request[AnyContent] and returns a Result.

In other words f is a curried function. You could call it as f(user)(request) to get back a Result.

like image 185
sepp2k Avatar answered Oct 20 '22 08:10

sepp2k


def withAuth(f: => String => Request[AnyContent] => Result) means, that f is a by-name parameter, and you can write something like this:

withAuth {
  logger.info("Here we go")
  ...
  chooseTheAction("list")
}

where chooseTheAction takes a String and returns a function performing a request, Request[AnyContent] => Result

like image 41
idonnie Avatar answered Oct 20 '22 09:10

idonnie