Demystify example code from playframework (Security.scala) - 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)

Related

How should I get B form A => B

I'm new to Scala, and I'm running into this strange situation.
def bar[A, B](implicit foo: A => B): B = {
// do something
foo
}
And then I got error like
require B but found A => B
How should I get B form A => B
Here's the reason why I did this, I have two functions:
def funcA: String = {
def getStrA: String = "A"
// then there's the same operation in both functions
Try{ } match {
case Success(_) => getStrA
case Failure(_) => // exactlly same error handler in both function
}
}
def funcB: Int = {
def doSomething(x: Int): Int = {
// do something
x / 1
}
val x = 1
Try{ } match {
case Success(_) => doSomething(1)
case Failure(_) => // exactlly same error handler in both function
}
}
Here's what I want to achieve
def funcA: String = {
implicit def getStrA: String = "A"
bar
}
def funcB: Int = {
val x = 1
implicit def doSomething(x: Int): Int = {
// do something
x / 1
}
bar
}
def bar[A, B](implicit foo: A => B): B = {
Try{ } match {
case Success(_) => foo
case Failure(_) => // exactlly same error handler in both function
}
}
You have a conversion from A to B. You need to return B. The only way to do this is to pass A into the function. This signature has an implied assumption that you have some valid A value (most likely hardcoded) that you will always use here.
def bar[A, B](implicit foo: A => B): B = {
val a: A = ... // hmm...
foo(a)
}
Considering, that A is parametric, then you are either missing some information, or this A is impossible to create (it cannot be null because not all types can take null as a value), so you might need to throw exception in such case. Probably you are either missing some A provider or you should always fail this operation.
UPDATE:
There is no need for using implicits at all in your code:
def bar[B](f: onSuccess: A => B) =
Try{ some operations } match {
case Success(value) => onSuccess(value)
case Failure(_) => // error handler
}
def funcA = bar(_ => "A")
def funcB = bar(_ => 1)

Scala get value from lambda

I want to get value from function that passed as parameter and returns Option[Int], after that if I have None throw an exception and in any other case return value
I tried to do like this:
def foo[T](f: T => Option[Int]) = {
def helper(x: T) = f(x)
val res = helper _
res match {
case None => throw new Exception()
case Some(z) => z
}
I call it like this:
val test = foo[String](myFunction(_))
test("Some string")
I have compilation error with mismatched types in match section (Some[A] passed - [T] => Option[Int] required)
As I understood res variable is reference to the function and I cannot match it with optional either call get\gerOrElse methods.
Moreover I probably just dont get how the underscore works and doing something really wrong, I'm using it here to pass a something as parameter to function f, can you explain me where I made a mistake?
helper is a method taking a T and returning an Option[Int].
res is a function T => Option[Int].
Difference between method and function in Scala
You can't match a function T => Option[Int] with None or Some(z).
You should have an Option[Int] (for example the function applied to some T) to make such matching.
Probably you would like to have
def foo[T](f: T => Option[Int]) = {
def helper(x: T) = f(x)
val res = helper _
(t: T) => res(t) match {
case None => throw new Exception()
case Some(z) => z
}
}
or just
def foo[T](f: T => Option[Int]): T => Int = {
t => f(t) match {
case None => throw new Exception()
case Some(z) => z
}
}
or
def foo[T](f: T => Option[Int]): T => Int =
t => f(t).getOrElse(throw new Exception())

Scala higher order function issue

My aim: To minimize lines of code.
Have a few function like f1, f2 ...
f1(A: String)
f2(A: String, B: Long, C: User)
Want to process it with high order function approach.
def processf1(request: Request[AnyContent], f: (String) => String)
def processf2(request: Request[AnyContent], f: (String, Long, User) => String) = {...}
Can I create ONE common process function for f1, f2 ?
Any ideas ?
Thanks.
You could parametrize processf types:
def processf[S,T](request: Request[S], f: T => String) = ...
Examples of use:
processf(new Request[Int], (x: String) => x)
processf(new Request[Int], (x: (String, Long, User)) => x._1)
Thanks for the answer, but not so clear for me, could please clarify
for example 3 function which have duplicate like RequestUtil.getRequestParams
private def regUser(request: Request[AnyContent], f: (String) => String): String = {
RequestUtil.getRequestParams(request, APPConst.USER) match {
case Some(map) => f(map(APPConst.USER))
case None => JsonUtil.toJson(APPConst.ERROR -> APPConst.POST_PARAMS_EMPTY_MISMATCH)
}
}
private def regDog(request: Request[AnyContent], f: (Dog, Enum, String, String) => String): String = {
RequestUtil.getRequestParams(request, APPConst.Dog) match {
case Some(m) => process(m, f)
case None => JsonUtil.toJson(APPConst.ERROR -> APPConst.POST_PARAMS_EMPTY_MISMATCH)
}
}
private def regCat[T](request: Request[AnyContent], f: (Cat, Enum) => String): String = {
RequestUtil.getRequestParams(request, APPConst.CAT) match {
case Some(map) => process(map, f)
case None => JsonUtil.toJson(APPConst.ERROR -> APPConst.POST_PARAMS_EMPTY_MISMATCH)
}
}
and executions
def regUser = Action { request => Ok(views.html.index(regUserProcess(request, UserService.regUser)))}
def regDog = Action { request => Ok(views.html.index(regCurrProcess(request, UserService.regDog)))}
def regCat = Action { request => Ok(views.html.index(mainProcess(request, UserService.regCat)))}
As you can see 3 different functions with different count parameters UserService.regUser, UserService.regDog, UserService.regCat functions

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)