Params list in Scala function. Can someone explain the code? - scala

Can someone explain the Scala code used in trait Secured of playframework sample app zentask:
def IsAuthenticated(f: => String => Request[AnyContent] => Result) = Security.Authenticated(username, onUnauthorized) { user =>
Action(request => f(user)(request))
}
I've just started to learn Scala and can not figure out this sequence f: => String => Request[AnyContent] => Result . What does it mean? I can not find any examples in manuals that use several => in place of parameters list for function.
What am I missing?

Maybe it's easier if you add some parantheses:
f: => (String => (Request[AnyContent] => Result))
f is a call-by-name parameter; it's a function that takes a String and returns: a function that takes a Request[AnyContent] and returns a Result.

f is a function that, given a String will produce a function that waits for a Result[AnyContent] to provide a Result.
Then at line 2. you pass to f the userparam, which must be a String and you pass the request param to the resulting function.
This way of passing parameters is called currying. A both short and a bit more complex example can be found there: http://www.scala-lang.org/node/135

Related

Scala - Passing a function to Future.apply

I'm learning Scala and just getting familiar with syntax. I see that Future.apply takes a function as the work to do.
The following works perfectly:
val future = Future { doWork(1) }
However just for experimentation I tried some other ways to do it, and neither work appropriately.
val future = Future(() => doWork(1))
This results in the lambda becoming the completion value of the future, instead of the return value of doWork(1).
val work: () => Int = () => doWork(index)
val future = Future(work)
The same situation here. Could someone explain why passing the function as the work to be done is instead resulting in the function actually becoming the return value of the work being done. Also how would I go about this. Thanks!
The signature of method called in Future {...} is def apply[T](body: =>T) where => T is a by-name parameter. See this documentation for more info.
By-name parameters are only evaluated when used.
In examples
Future(() => doWork(1))
and
val work: () => Int = () => doWork(index)
val future = Future(work)
You are passing as by-name parameter function of type () => Int or same as Function0[Int]. This function is returned in the Future when by-name parameter is evaluated.
The function is not evaluated as Future does not call apply or ().
It will be more understandable if you add type parameters to the Future in all examples. If doWork returns Int. In this case Future { doWork(1) } is Future[Int] whereas it is Future[Function0[Int]] in the second and third examples.
The correct usage would be
val work: () => Int = () => doWork(index)
val future = Future(work())

Is it possible to call a generically-typed function by passing in a class specified in a map?

Asking here because I'm pulling out my hair trying to figure out what exactly it is I need to do here.
I'm writing a batch-processing endpoint that attempts to convert the body of a request to a specific Scala case class before executing the logic within the endpoint itself.
This is as far as I currently got. First, I have a function executeWithType that takes a generic type, a controller method, and the request body and executes the controller method after converting the request body to the provided type. The request param is available in a scope outside this function.
def executeWithType[A](action: () => Action[A], batchRequest: BatchRequest): Future[Result] = {
action()(request.map(_ => batchRequest.body.map(_.as[A]).get))
}
Then, I have some code that checks what endpoint to call and what type to cast to depending on what's in the BatchRequest itself.
val res: Future[Result] = (batchRequest.method, batchRequest.endpoint) match {
case ("POST", "/endpoint1") => {
executeWithType[EndpointOneType](controller.endpointOne _, batchRequest)
}
case ("POST", "/endpoint2") => {
executeWithType[EndpointTwoType](controller.endpointTwo _, batchRequest)
}
case _ => Future.successful(NotFound)
}
The above works perfectly fine - however, I want to avoid this sort of tuple-matching with individual cases if possible, and specify a Map that does this instead. In my ideal world, the end result of the code block immediately above would look like this:
val actions = Map(
Seq("POST", "/endpoint1") -> (controller.endpointOne _, EndpointOneType),
Seq("POST", "/endpoint2") -> (controller.endpointTwo _, EndpointTwoType)
)
val res = actions.get(Seq(batchRequest.method, batchRequest.endpoint)) match {
case Some(action) => {
executeWithType[action._2](action._1, batchRequest)
}
case _ => Future.successful(NotFound)
}
Is this possible at all? I've been trying to fight with it but my understanding of reflection in Scala is really weak, so I'm not sure exactly how I'd go about doing this. I've tried a bunch of classOf and typeTag and Class[_] stuff but I'm basically swinging in the dark. Hoping someone more knowledgeable than I am could help me out.
The big things are:
What needs to go in the second space of the tuple in the value of the Map? How do you pass a Class variable?
How do we use that class-as-a-variable to call a generically typed method?
How do we use that class-as-a-variable to call a generically typed method?
You can't. But I'd like to suggest an alternate solution.
Just define a local class instead of tuples:
class RequestAction[A](action: () => Action[A]) {
def apply(request: BatchRequest) = executeWithType(action, request)
}
val actions = Map(
Seq("POST", "/endpoint1") -> new RequestAction(controller.endpointOne _), // type parameter is inferred
Seq("POST", "/endpoint2") -> new RequestAction(controller.endpointTwo _)
)
val res = actions.get(Seq(batchRequest.method, batchRequest.endpoint)) match {
case Some(action) => action(batchRequest)
case _ => Future.successful(NotFound)
}
(while this depends on code not shown in the question, it looks likely that you can simplify by passing Action[A] instead of () => Action[A]).

scala Functonal abstraction (List) not working

please help me out in this scala throwing an error in below context
def SelectValues(list: List[Int],sel:Int => Boolean) ={
var sum =0
list.foreach{ e =>
if(sel(e)) sum += e
}
sum
println(sum)
}
println(SelectValues(List(1,2){e => true}))
enter image description here'screen shot
The problem is in your println line:
println(SelectValues(List(1,2){e => true}))
You don't have a comma between the List(1,2) and the {e => true} this means that you are sending a single parameter to SelectValues:
List(1,2){e => true}
This is equivalent to:
List(1,2)(f)
where f is the function. i.e. you are trying to call a function (apply in this case) on the resulting object from List(1,2) and not sending the second parameter (sel)).
the compiler analyzes first the SelectValues signature (before figuring out what your object is) and sees only one parameter.
To solve this, simply add the missing comma:
println(SelectValues(List(1,2), {e => true}))

How to use PartialFunction.applyOrElse

I have a PartialFuncton[Throwable,Future[Result]] called errorMap to transform an throwable to a result or failed future. I can do it via lift and getOrElse like this:
val x: Future[Result] = errorMap.lift(e).getOrElse(Future.failed(e))
I figure the same should be achievable with applyOrElse, but I can't seem to figure out how to call it to achieve this end. Am I misunderstanding what applyOrElse is for?
The second argument to applyOrElse takes a function-- in your case a (Throwable) => Future[Result]
Pass it a function like this:
errorMap.applyOrElse(e, _ => Future.failed(e))
or simply
errorMap.applyOrElse(e, Future.failed)

Unclear notation in Scala code snippet

I am going through the Principels of Reactive Programming course at Coursera and noticed few times a notation which I cannot completely comprehend. So I hope you can help me to understand.
Here is the code snippet:
def retry(noTimes:Int)(block: => Future[T]): Future[T] = {
val ns: Iterator[Int] = (1 to noTimes).iterator
val attempts: Iterator[Future[T]] = ns.map(_ => () => block)
val failed = Future.failed(new Exception)
attempts.foldLeft(failed) ((a, block) => a recoverWith {block()})
}
It is not clear to me why in the attempts value definition it is not simply ns.map(_ => block) ?
Type of the attempts value is Iterator[Future[T]] and map as it written in the snippet seems to me should produce Iterator[() => Future[T]]. Could you help to grasp it?
With this:
ns.map(_ => block)
block would be executed directly, that's not what the author would want.
Similar to Call-By-Value parameter.
However, with this:
ns.map(_ => () => block), it is similar to Call-By-Name parameter, meaning that the block code would be executed only when explicitly called in the underlying function.
If I correctly remembered, the author of the course was saying something like:
"Sit down, take a coffee and deeply analyse the function in order to figure out why we need to execute the block code lazily" ;)
UPDATE-------
In the wrapping method's signature, block is declared as a call-by-name parameter:
block: => Future[T]
Therefore, the Future[T] well corresponds to () => block explaining why:
val attempts: Iterator[Future[T]] is not val attempts: Iterator[() => Future[T]]