Scala + Play Framework: Action composition explanation needed - scala

This is the action composition taken from a sample that comes with the Play Framework
def IsAuthenticated(f: => String => Request[AnyContent] => Result) = Security.Authenticated(username, onUnauthorized) { user =>
Action(request => f(user)(request))
}
So, Security.Authenticated takes an username: RequestHeader => Option[String] and onAuthorized: RequestHeader=>SimpleResultand the second group of parantheses take String => Action[A]
And then in the controller I have:
def index = isAuthenticated { ...code }}
The code above is this, so I assume this is the f function => String => Request[AnyContent] => Result. Now, what I don't understand is what really happens here. I am not talking about User.findByEmail...., I'm talking about username => _ => .... What would the signature of this function look like if I called it directly?
username => _ =>
User.findByEmail(username).map { user =>
Ok(
html.dashboard(
Project.findInvolving(username),
Task.findTodoInvolving(username),
user
)
)
}.getOrElse(Forbidden)
If there was def isAuthenticated(f: => Request[AnyContent] => Result) I'd know how to use it and I'd understand it. But the extra "data" is confusing me.
UPDATE:
I guess I found something:
def f2: String => Int => List[Char] = x => _ => x.toList
And this would be called as:
f2("Andrew")(2) //there can be anything replacing 2 because I don't have access to it anyway
So the function above that I asked primarily about would be:
def f: => String => Request[AnyContent] => Result = username => _ => User.find.....
Am I right?
I get a "No by name parameter allowed here error".
If they don't use the second parameter why are they using String => Request => Result and not just simply String => Result?

That function definition is actually a curried function definition.
String => Request => Result actually means: f(s:String):(r:Request)=>Result ie a function that takes a String and returns a function that takes a Request and returns a Result.
Check out the part "Spicing up your functions": http://danielwestheide.com/blog/2013/01/30/the-neophytes-guide-to-scala-part-11-currying-and-partially-applied-functions.html

For me, the examples at https://github.com/mariussoutier/PlayBasics/tree/master/play-2.2-migration are very enlightening.

Related

Scala: am I writing a curried function?

I have to transform the following function into a curried function:
def findAllUsed(t: List[Task]): List[String] = {
t.flatMap(x => x.resources.map(x => x.FIELD_TO_SEARCH)).distinct
}
So I did this:
def findAllUsed(t: List[Task], f: Resource => String): List[String] = {
t.flatMap(x => x.resources.map(f)).distinct
}
findAllUsed(taskSchedules, ((x: Resource) => { x.id }))
findAllUsed(taskSchedules, ((x: Resource) => { x.kind }))
The problem is that it seems to me that I am confusing currying with higher order functions.
Can anyone if I am doing it right and if not, how could I manage to do it right?
I'm assuming the exercise meant something like this:
// separate into two argument lists
def findAllUsed(t: List[Task])(f: Resource => String): List[String] = {
t.flatMap(x => x.resources.map(f)).distinct
}
// apply the first argument list once,
// getting a curried function as a result
val curried = findAllUsed(taskSchedules)
// now you can use it twice with different inputs for the second argument list:
curried(x => x.id)
curried(x => x.kind)
The benefit here (if there is any), is the removal of the duplication passing taskSchedules to your function: since it has "it's own" argument list, you can pass it once, assign the result into a value (curried), and then reuse it over and over;
p.s. the type of curried is (Resource => String) => List[String] - it's a function from a Resource => String (which is another function...) to a list of strings.

Demystify example code from playframework (Security.scala)

In the file https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/play/api/mvc/Security.scala, it has the following example code in a comment:
//in a Security trait
def username(request: RequestHeader) = request.session.get("email")
def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Application.login)
def isAuthenticated(f: => String => Request[AnyContent] => Result) = {
Authenticated(username, onUnauthorized) { user =>
Action(request => f(user)(request))
}
}
//then in a controller
def index = isAuthenticated { username => implicit request =>
Ok("Hello " + username)
}
So I tried to write some similar code:
def test1(a: =>Int=>Int=>Int):String="1"
test1 {1 => 1 => 1} // But this line doesn't compile.
I called it the same way as isAuthenticated is called, so why doesn't my code compile?
test1 {1 => 1 => 1} doesn't compile because {1 => 1 => 1} isn't a valid function definition. {x => y => 1}, on other hand, does compile. This is because 1 cannot be used as the name for a parameter.
Take a look at what happens when you paste def test1(a: =>Int=>Int=>Int):String="1" into the Scala REPL:
test1: (a: => Int => (Int => Int))String
test becomes defined as a function that accepts an another function as it's parameter. Notice the extra parenthesis in the REPL output. a is a function that maps Int to another function Int => Int.
So something like this would be more appropriate:
def a(i: Int): Int => Int = {j: Int => i + j}
test1(a)

How do I interprete a sequence of => in Scala?

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))
}
=> 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'
A couple of additions to the accepted answer
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)
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)
}
)
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))
}

Understanding a Scala function from Play framework zentask example

This is a function in the zentask example in Application.scala.
I'm trying to understand it...
What does the f: => String mean?
What about the chaining of f: => String => Request[AnyContent] => Result
/**
* Action for authenticated users.
*/
def IsAuthenticated(f: => String => Request[AnyContent] => Result) =
Security.Authenticated(username, onUnauthorized) { user =>
Action(request => f(user)(request))
}
A parameter of the form fn: => String represents a 'generator' (either a function or a value) that returns (or is) a String, so, for example, you might have a method defined as
def myMethod(fn: => String): String = "Fn output = " + fn
and call this as follows (the return types I use here can typically be inferred by the compiler, I'm just adding them for pedagogical purposes):
def myFn: String = "Hello!"
// Alternatively: def myFn(): String = "Hello!"
// or: val myFn: () => String = "Hello!"
// or most simply: val myString = "Hello!"
val output = myMethod(myFn) // output = "Fn output = Hello!"
Building on this, we can define a method that takes a function that turns a String into an Int, eg:
def my2ndMethod(fn: String => Int): Int = fn("4")
and call it as follows:
def my2ndFn(input: String) = 5 * input.toInt
// Alternatively: val my2ndFn: String => Int = input => 5 * input.toInt
val output2 = my2ndMethod(my2ndFn _) // output2 = 20
In the case you provide, you have a more complicated entity: something that returns (or is) a function that takes a String and returns a further function that in turn takes a Request[AnyContent] and (finally) returns a Result (phew!).
You can also think of this as taking a function defined and used as follows:
def authFn(username: String)(request: Request[AnyContent]): Result
val authenticatedResult = IsAuthenticated(authFn _)
Actually it is a bit tricky to figure out how the operator associates:
f: => String => Request[AnyContent] => Result
is the same as
f: (=> String) => (Request[AnyContent] => Result)
So f is a function that takes a => String and returns a function that takes a request and returns a result. As I indicated in my comment, have a look at Need plain english translation of the following scala snippet for an explanation of some of what's going on.
So why have => String as the first argument versus just String? My guess is that it comes into play if you intended the user to pass a function that has its first argument by name (meaning it is evaluated every time it is needed).
So say you have a method g:
def g(s: => String): String => String = arg => s + arg
If you want to write a method m that takes the method g as an argument, then you need to write it like this:
def m(f: (=> String) => (String => String)) = f("a")("b")
m(g) // compiles
If you write it like this:
def n(f: String => (String => String)) = f("a")("b")
n(g) // does not compile
// found : => String => (String => String)
// required: String => (String => String)

How do I secure file upload in Play! Framework (Scala)

I have implemented a Secured trait as described in the tutorial:
trait Secured {
...
def IsAuthenticated(f: => String => Request[AnyContent] => Result) = Security.Authenticated(username, onUnauthorized) { user =>
Action(request => f(user)(request))
}
...
}
And using it like this:
def list = IsAuthenticated { username => _ =>
...
}
Now, I have the following definition for file uploads:
def upload = Action(parse.multipartFormData) { request =>
...
}
Is it possible to combine IsAuthenticated and parse.multipartFormData so I am able to check the user during the file upload?
The version you implemented doesn't receive a BodyParser. In the tutorial there is a version that accepts BodyParsers:
def Authenticated[A](p: BodyParser[A])(f: AuthenticatedRequest[A] => Result) = {
Action(p) { request =>
request.session.get("user").flatMap(u => User.find(u)).map { user =>
f(AuthenticatedRequest(user, request))
}.getOrElse(Unauthorized)
}
}
Use this one. All the code you need is at the bottom of the page.
You may have to overload the function.
def IsAuthenticated[A](p: BodyParser[A])(f: => String => Request[A] => Result): Action[A] ={
...
}
def IsAuthenticated[AnyContent](f: => String => Request[AnyContent] => Result): Action[AnyContent] =
IsAuthenticated(BodyParsers.parse.anyContent)(f)
I've done something similar in my application.