How can I avoid duplicating work on a collectFirst call? - scala

I have something like this:
val yyy = aListOfObjects.collectFirst{
case x if(x.calc("input").isDefined) => x.calc("input").get
}
I have some list of things. Each thing has a method, calc, that does work to bring back an optional result, if the calculation was successful or not.
I want to go thru the list of things and bring back the calculated value of the first one that is successful, or None if none of them work.
The snip above does this, but... you'll see I call x.calc() twice. Assuming the call to calc is non-trivial, how can I avoid the double call? (I also don't want to pre-call calc() on all things since I only care about the first one that works.)

You can use the fact that Streams are lazy in scala:
aListOfObjects
.toStream
.flatMap { _.calc("input") }
.headOption
Or define your own extractor:
object Calc {
def unapply(x: TypeOfX) = x.calc("input")
}
Now, you can write: listOfObject.collectFirst { case Calc(x) => x }

Related

Better approach to convert Future to Boolean

I have a db query which returns a Future[String], the implementation does not matter, but the signature is something like this:
def getTicketType(id: Long): Future[String] = {...}
And imagine I have a list of ids which i would want to retrieve ticket types from those ids. so something like this:
val listOfIds: List[Long] = ... (from somewhere else of the code)
val ticketTypesFuture: Future[List[String]] = Future.sequence(listOfIds.map(getTicketType))
So far so good, but there is another function, which is called within the main process, that HAS to return a Boolean or an Option[Boolean] value, since it's result is used in the main process which holds a gigantic for comprehension, combined of some Either[Int, Option[JsValue]]'s. The way I'm doing it right now (which I believe is the worst way of implementing such thing :) ), is this:
def thatFunction(): Boolean = {
// ... val listOfIds, ticketTypesFuture defined above
var result = false // here is the nasty code :)
val futureResult: Future[Boolean] = ticketTypesFuture.map { ticketTypes =>
if (!ticketTypes.forall(someCondition)) {
// some code which returns either true or false
} else false
}
futureResult.omComplete {
case Success(value) => result = value
case _ => result = false
}
result
}
But there must be a better approach to do this, so I would appreciate any help!
The sane option is to go the other way and make your "gigantic for comprehension, combined of some Either[Int, Option[JsValue]]'s" work with futures. Wrap the part before and after the query using Future.apply or Future.successful, and you should be fine. Or if it contains other database/API accesses, make them return Future as well.
If you can't, your choice is:
use Await.result as in Tim's answer, which loses any benefit of futures. If you really want that, consider using a library which doesn't return a future in the first place. But this may be a placeholder until you switch.
use Future#value if you want not to wait and just do something else if the result is not ready. For example you might show some old results, or an empty list until you get data.
(After writing this, I saw #jwvh already said basically the same in a comment, hopefully it still helps to have a more expanded version.)
If you must convert Future[Boolean] to Option[Boolean] then you need to wait for the Future using Await.result. This will throw an error if the Future fails, so wrap it in a Try.
val futureResult: Future[Boolean] = ???
Try(Await.result(futureResult, Duration.Inf)).toOption
But the better solution is to convert the calling code to accept a Future and avoid blocking.
As you can see in the answers and comments, multiple approaches have been discussed, which include:
1- waiting for the Future to complete (using mutation, Await, ...) which are the worst of the approaches, so just don't do that :)
2- mapping on the value like this: futureResult.value.map(t => t.isSuccess && t.get)
and some other solutions.
As #jwh mentioned, another solution is to handle it properly, anything that touches futureResult becomes a Future!
But since I couldn't change all the calculations and functions inside that for comprehension, I placed this Future[Boolean] condition outside of the for loop, and everythin is just fine.

Difference between Future[Any] and Future[_]

Okay, I guess question is already complete in the title.
Nothing big, but I am just wondering. I have a method which returns either a correct value or an error code enum item. For example something like this:
def doMyStuff(): Future[_] = {
val result = db.queryMyData().map {
case some(data) =>
val modifiedData = data.doStuff()
modifiedData
case None =>
Errors.THIS_IS_FALSE
}
result
}
Where db.queryMyData() returns a Future, and data.doStuff() just modifies the data.
Now I have intuitively written Future[_], cause the return value is flexible. But when looking in other libraries I've seen Future[Any] used. Which seems to be logic too, when you use a match-case on the return of the function to check which data it is.
The code which uses that is for example something like this:
doMyStuff().map {
case data: MyDataType => // Blah blah
case Errors.Value => // error handling
}
So, my questions is: What's the difference between the use of Any or _ here, and why should I use the correct one?
It is a matter of semantics:
The Existential TypeT[_] means there is a class/type at the position of _ for which I do not care at all but it must be there.
T[Any] means there has to be a subclass Any present.
The difference comes into play when you want to serialize the underlying class.
If you just use _ without any typebounds you will not be able to use some of the many Scala JSON libraries.

A design pattern for chaining together Trys that may not all be neccessary

I have a lot of code that has to call functions that return Try. The only reason that they return Try is to show errors. The success value isn't actually important.
Sometimes not all these functions need to be called, depending on some conditionals. For example, suppose I am given an update form and I only want to update the database for things that were changed.
I can do this with
for {
_ <- if(precidate1) funtionReturningTry else Success(-1)
// ...
_ <- if(precidateN) anotherFuntionReturningTry else Success(-1)
} yield someUnrelatedId
One problem with this is that it can create quite a bit of clutter since we must create some discarded Success value to show that we are skipping that step of the comprehension. For more complicated types, this is a bit messier since we must return some dummy type. Above all, those else statements are nothing but noise.
It'd be ideal if we could use something like guards. We can't use guards here because if a guard fails, the entire comprehension fails.
Obviously a for comprehension works great when all our function calls are necessary, but it doesn't seem to make it easy to skip function calls. Does anyone know a clean design pattern for chaining together such statements when some may be optional?
Why not just wrap this in another function? If you don't care about the return types of Try[A] (other than failures), then you can discard them to Unit, for example.
def tryIf[A](condition: Boolean)(f: => Try[A]): Try[Unit] = {
if(condition) f.map(_ => ()) else Success(())
}
Then your for-comprehension would look like this:
for {
_ <- tryIf(precidate1)(funtionReturningTry)
...
_ <- tryIf(precidateN)(anotherFuntionReturningTry)
} yield ...
No more elses and dummy values for arbitrary types.

Converting thunk to sequence upon iteration

I have a server API that returns a list of things, and does so in chunks of, let's say, 25 items at a time. With every response, we get a list of items, and a "token" that we can use for the following server call to return the next 25, and so on.
Please note that we're using a client library that has been written in stodgy old mutable Java, and doesn't lend itself nicely to all of Scala's functional compositional patterns.
I'm looking for a way to return a lazily evaluated sequence of all server items, by doing a server call with the latest token whenever the local list of items has been exhausted. What I have so far is:
def fetchFromServer(uglyStateObject: StateObject): Seq[Thing] = {
val results = server.call(uglyStateObject)
uglyStateObject.update(results.token())
results.asScala.toList ++ (if results.moreAvailable() then
fetchFromServer(uglyStateObject)
else
List())
}
However, this function does eager evaluation. What I'm looking for is to have ++ concatenate a "strict sequence" and a "lazy sequence", where a thunk will be used to retrieve the next set of items from the server. In effect, I want something like this:
results.asScala.toList ++ Seq.lazy(() => fetchFromServer(uglyStateObject))
Except I don't know what to use in place of Seq.lazy.
Things I've seen so far:
SeqView, but I've seen comments that it shouldn't be used because it re-evaluates all the time?
Streams, but they seem like the abstraction is supposed to generate elements at a time, whereas I want to generate a bunch of elements at a time.
What should I use?
I also suggest you to take a look at scalaz-strem. Here is small example how it may look like
import scalaz.stream._
import scalaz.concurrent.Task
// Returns updated state + fetched data
def fetchFromServer(uglyStateObject: StateObject): (StateObject, Seq[Thing]) = ???
// Initial state
val init: StateObject = new StateObject
val p: Process[Task, Thing] = Process.repeatEval[Task, Seq[Thing]] {
var state = init
Task(fetchFromServer(state)) map {
case (s, seq) =>
state = s
seq
}
} flatMap Process.emitAll
As a matter of fact, in the meantime I already found a slightly different answer that I find more readable (indeed using Streams):
def fetchFromServer(uglyStateObject: StateObject): Stream[Thing] = {
val results = server.call(uglyStateObject)
uglyStateObject.update(results.token())
results.asScala.toStream #::: (if results.moreAvailable() then
fetchFromServer(uglyStateObject)
else
Stream.empty)
}
Thanks everyone for

What's the best way to open up a list with 0 or 1 options?

In Scala I have a List with an optional Option. This arises for example when you use for comprehension on a List and your yield returns an Option. In my case I was processing a JSON object and using for comprehension on the list of fields (List[JField]).
What's the best way to open up the list and map List() to None and List(Some(a)) to Some(a)?
A first approach would be
def headOrNone[A](list:List[Option[A]]) =
list match {
case Nil => None
case a::Nil => a
}
Another approach
def headOrNone[A](list:List[Option[A]]) = list.headOption.getOrElse(None)
A third approach (a variation on the headOption implementation)
def headOrNone[A](list:List[Option[A]]) = if (list.isEmpty) None else list.head
I personally prefer the third approach. Is there a better name for this function than headOrNone and what is the idiomatic scala way to write it?
You're solving a problem that probably shouldn't have been created. Instead, you probably want
for (x <- list) yield f(x) // Yields Option
to be
list.flatMap(f)
and then you'll have either zero or one things in your list to begin with (which you can extract using headOption).
How about this:
def headOrNone[A](list: List[Option[A]]) = list.flatten.headOption
headOrNone(List(Some(4))) // Some(4)
headOrNone(List()) // None
Though the first choice has the advantage of giving you an error if you happen to have list with more than one item, which, according to your description, seems like an error condition.
But personally, I would re-evaluate the code that produces the List[Option[A]] and see if there's a way to just have it return the right thing in the first place!