Canonical way to define and execute a method that outputs Unit? - scala

I have a list of methods (functions) that output Unit:
var fns:List[() => Unit] = Nil
def add(fn:() => Unit) = fns :+= fn // a method to add to the list
I want to add println("hello") to the list.
add(() => println("hello"))
Is there a better way than using the ugly parenthesis.
I would have preferred:
add (println("hello")) // error here
def myCoolMethod = {
// do something cool
// may return something, not necessarily Unit
}
add (myCoolMethod) // error here
I tried var fns:List[_ => Unit] and var fns:List[Any => Unit], fns:List[() => Any], etc without getting what I want.
Second question is how do I execute the methods in the list when I want to. I got it to work with:
fns foreach (_.apply)
Is there a better way?

You could use by-name parameter instead of function with empty parameters list like this:
var fns:List[() => Unit] = Nil
def add(fn: => Unit) = fns :+= (fn _)
add{ print("hello ") }
def myCoolMethod = { println("world") }
add(myCoolMethod)
fns foreach {_.apply}
// hello world
You could use _() instead of _.apply: fns foreach {_()}, but I'd prefer _.apply.

Related

How to save output of repeat loop in parquet file?

I have a word "hi" written in loop.
implicit class Rep(n: Int) {
def times[A](f: => A) { 1 to n foreach(_ => f) }
}
// use it with
130.times { println("hi") }
How to save output?
There are some bugs in your code, here is a correct one:
implicit class Rep(n: Int) {
def times[A](f: => A): Seq[A] = { 1 to n map(_ => f) }
}
// use it with
val myHis = 130.times { "hi" } // returns Vector(hi, hi, hi, hi, hi, ...)
add = otherwise the functions return type is Unit- always add the return type explicit in such cases (: Seq[A]) and the compiler would have helped you.
use map instead of foreach as foreach returns again Unit
println("hi") returns again Unit. The last statement is returned, so it must be the value you want.
To write a file of this:
new java.io.PrintWriter("filename") { write(myHis.mkString(", ")); close }
Be aware this simple example does not handle exception properly - but I think myHis.mkString(", ") is what you are looking for.

How to convert a class T object into a Future[T] object in akka

I am trying to do something with akka and scala and i am new to it. I want to append the result of an 'Any' Future into one of the fields in the class
So i have class called T defined as
class T {
var a: String =_
var result = List[Any]= List()
}
Now i have a variable which receives a future value
var futureResult:Future[Any] = //receives a future value
in a function called addResult which takes an T object and returns a future T object.
def addResult(obj1:T):Future[T] ={
var obj2:T = new T()
obj2.a = obj1.a
obj2.result = obj1.result
//I want to append results of futureResult into obj2.result when it is completed
// obj2.result = futureResult :: obj2.result
return Future(obj2)
}
I have to finally call this function from a flow.
val b = Flow[T].mapAsync[T](1)(addResult(_))
First, as #riccardo.cardin noted using T as a name of a class is very bad idea, because of T usual points to generic.
However, you can put any logic in Future with a simple closure, in your case, it looks like this:
Future {
new T("some string", 1 :: 2 :: 3 :: Nil)
}
After that, you can combine asynchronous computation via flatMap, map or with for comprehensive or even use cats black magic with |#|:
for {
f1 <- future1()
f2 <- future2(f1.id)
} yield f2.name
(future1 |#| future2) map { _ - _ }
In your case this transformation depends from logic of your code.
You can change the commented line like this:
futureResult.map { res =>
obj2.result = res :: obj2.result
obj2
}
And then you won't need the last line.

Scala return variable type after future is complete Add Comment Collapse

I've got a problem with returning a list after handling futures in scala. My code looks like this:
def getElements(arrayOfIds: Future[Seq[Int]]): Future[Seq[Element]] = {
var elementArray: Seq[Element] = Seq()
arrayOfIds.map {
ids => ids.map(id => dto.getElementById(id).map {
case Some(element) => elementArray = elementArray :+ element
case None => println("Element not found")
})
}
arrayOfIds.onComplete(_ => elementArray)
}
I'd like to do something like .onComplete, however the return type is
Unit and I'd like to return a Future[Seq[Whatever]]. Is there clean way to handle futures like this? Thanks!
Please provide the type of function dto.getElementById. If it is Int => Future[Option[Element]], then:
def getElements(arrayOfIds: Future[Seq[Int]]): Future[Seq[Element]] = {
val allElements: Future[Seq[Option[Element]]] = arrayOfIds.flatMap( ids =>
Future.sequence(ids.map(dto.getElementById))
)
allElements.map(_.flatMap{
case None => println();None
case some => some
})
}
Without logging, it would be:
arrayOfIds.flatMap( ids => Future.traverse(ids.map(dto.getElementById))(_.flatten))
Instead of assigning the result to a mutable variable, return it from the continuation of the Future. You can use flatMap to extract only the Element results which actually contain a value:
def getElements(arrayOfIds: Future[Seq[Int]]): Future[Seq[Element]] = {
arrayOfIds.flatMap(id => Future.fold(id.map(getElementById))(Seq.empty[Element])(_ ++ _))
}

declare variable in custom control structure in scala

I am wondering if there is a way to create a temp variable in the parameter list of a custom control structure.
Essentially, I would like create a control structure that looks something like the
for loop where I can create a variable, i, and have access to i in the loop body only:
for(i<- 1 to 100) {
//loop body can access i here
}
//i is not visible outside
I would like to do something similar in my code. For example,
customControl ( myVar <- "Task1") {
computation(myVar)
}
customControl ( myVar <- "Task2") {
computation(myVar)
}
def customControl (taskId:String) ( body: => Any) = {
Futures.future {
val result = body
result match {
case Some(x) =>
logger.info("Executed successfully")
x
case _ =>
logger.error(taskId + " failed")
None
}
}
}
Right now, I get around the problem by declaring a variable outside of the custom control structure, which doesn't look very elegant.
val myVar = "Task1"
customControl {
computation(myVar)
}
val myVar2 = "Task2"
customControl {
computation(myVar2 )
}
You could do something like this:
import scala.actors.Futures
def custom(t: String)(f: String => Any) = {
Futures.future {
val result = f(t)
result match {
case Some(x) =>
println("Executed successfully")
x
case _ =>
println(t + " failed")
None
}
}
}
And then you can get syntax like this, which isn't exactly what you asked for, but spares you declaring the variable on a separate line:
scala> custom("ss") { myvar => println("in custom " + myvar); myvar + "x" }
res7: scala.actors.Future[Any] = <function0>
in custom ss
ss failed
scala> custom("ss") { myvar => println("in custom " + myvar); Some(myvar + "x") }
in custom ss
Executed successfully
res8: scala.actors.Future[Any] = <function0>
scala>
Note that the built-in for (x <- expr) body is just syntactic sugar for
expr foreach (x => body)
Thus it might be possible to achieve what you want (using the existing for syntax) by defining a custom foreach method.
Also note that there is already a foreach method that applies to strings. You could do something like this:
case class T(t: String) {
def foreach(f: String => Unit): Unit = f(t)
}
Note: You can also change the result type of f above from Unit to Any and it will still work.
Which would enable you to do something like
for (x <- T("test"))
print(x)
This is just a trivial (and useless) example, since now for (x <- T(y)) f(x) just abbreviates (or rather "enlongishes") f(y). But of course by changing the argument of f in the above definition of foreach from String to something else and doing a corresponding translation from the string t to this type, you could achieve more useful effects.

How do I create a partial function with generics in scala?

I'm trying to write a performance measurements library for Scala. My idea is to transparently 'mark' sections so that the execution time can be collected. Unfortunately I wasn't able to bend the compiler to my will.
An admittedly contrived example of what I have in mind:
// generate a timing function
val myTimer = mkTimer('myTimer)
// see how the timing function returns the right type depending on the
// type of the function it is passed to it
val act = actor {
loop {
receive {
case 'Int =>
val calc = myTimer { (1 to 100000).sum }
val result = calc + 10 // calc must be Int
self reply (result)
case 'String =>
val calc = myTimer { (1 to 100000).mkString }
val result = calc + " String" // calc must be String
self reply (result)
}
Now, this is the farthest I got:
trait Timing {
def time[T <: Any](name: Symbol)(op: => T) :T = {
val start = System.nanoTime
val result = op
val elapsed = System.nanoTime - start
println(name + ": " + elapsed)
result
}
def mkTimer[T <: Any](name: Symbol) : (() => T) => () => T = {
type c = () => T
time(name)(_ : c)
}
}
Using the time function directly works and the compiler correctly uses the return type of the anonymous function to type the 'time' function:
val bigString = time('timerBigString) {
(1 to 100000).mkString("-")
}
println (bigString)
Great as it seems, this pattern has a number of shortcomings:
forces the user to reuse the same symbol at each invocation
makes it more difficult to do more advanced stuff like predefined project-level timers
does not allow the library to initialize once a data structure for 'timerBigString
So here it comes mkTimer, that would allow me to partially apply the time function and reuse it. I use mkTimer like this:
val myTimer = mkTimer('aTimer)
val myString= myTimer {
(1 to 100000).mkString("-")
}
println (myString)
But I get a compiler error:
error: type mismatch;
found : String
required: () => Nothing
(1 to 100000).mkString("-")
I get the same error if I inline the currying:
val timerBigString = time('timerBigString) _
val bigString = timerBigString {
(1 to 100000).mkString("-")
}
println (bigString)
This works if I do val timerBigString = time('timerBigString) (_: String), but this is not what I want. I'd like to defer typing of the partially applied function until application.
I conclude that the compiler is deciding the return type of the partial function when I first create it, chosing "Nothing" because it can't make a better informed choice.
So I guess what I'm looking for is a sort of late-binding of the partially applied function. Is there any way to do this? Or maybe is there a completely different path I could follow?
Well, thanks for reading this far
-teo
The usual pattern when you want "lazy" generics is to use a class with an apply method
class Timer(name: Symbol) {
def apply[T](op: => T) = time(name)(op)
}
def mkTimer(name: Symbol) = new Timer(name)