4
votes

I'm currently starting with play framework, but my Scala knowledge is not sufficient.

As I know the => indicates that IsAuthenticated has some kind of functions as parameter. I found out as well the f: => String... is a function with no input value. But how do I interprete the complete line with its 3 => ? And further down, what exactly happens in the second line with => f(user)(request)? What is the target function for user and request object?

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

2 Answers

5
votes
=> String => Request[AnyContent] => Result

is easier to read with parens added:

=> (String => (Request[AnyContent] => Result))

You can try this in the REPL. For example:

scala> def foo(f: => String => Int => Char): Char = f("abcdefgh")(4)
foo: (f: => String => (Int => Char))Char

In this example, f is a nullary function call-by-name parameter that returns a function (let's call that function g). g is a function that accepts a String parameter and returns yet another function (h). h is a function that accepts an Int parameter and returns a Char.

Example invocation:

scala> foo { s: String => { i: Int => s.charAt(i) } }
res0: Char = e

Let's walk through the type of each expression in the method body as it's evaluated:

  • f
    • Type: String => (Int => Char)
    • Value: { s: String => { i: Int => s.charAt(i) } }
  • f("abcdefgh")
    • Type: Int => Char
    • Value: { i: Int => "abcdefgh".charAt(i) }
  • f("abcdefgh")(4)
    • Type: Char
    • Value: 'e'
0
votes

A couple of additions to the accepted answer

  1. About Security.Authenticated

    Security.Authenticated(username, onUnauthorized) { user => Action(request => f(user)(request)) }

    Security.Authenticated - seems to be a function that takes two lists of parameters. The first list of parameters:

    (username:String, onUnauthorized:Boolean)
    

    and the second list is one argument:

    (g:User => Action)
    

    The complete signature can be something like:

    def Authenticated(username:String, onUnauthorized:Boolean)(g:User => Action)
    
  2. Action seems to be a class that takes a function in it's constructor:

    class Action(h:Request => Result)
    

    The argument to the constructor is a new function

    def hActual(request:Request):Result = f(user)(request)
    

    (the def should have user in the scope, because it is not given in arguments. For instance, hActual can be declared immediately before Action constructor call:

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

    )

  3. Also It seems so that the constructor can be called using curring:

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