Chaining futures and options idiomatically - scala

def foo(user, id): Future[Option[Bar]] =
bar(user, id).map(_.map(_.address.flatMap(_.street)))
.flatMap {
case Some(street) =>
baz(user, street).flatMap(_ => get(id))
case None => successful(None)
}
Function bar returns an Option[UserInfo], which I then map to a UserInfo. Address is also an Option so I flatMap that to have access to street. Then simply if there exists a street I want to call baz, if not then None. Ignore the business logic, it's made up for the example.
There's a problem with the code here as it won't compile.
Some(street) is an Option, since the flatMap on line 3 is being called on the result of the mapping on the first _, instead of _.address.
Whilst I could get this to work with some parenthesis juggling and so on, this code is starting to get hard to read and reason about.
Are for-comprehensions the answer?
P.S: There might be some type-information missing in this example so please ask and I will elaborate.
EDIT:
case class UserInfo(id: UserId, address: Option[Address])
case class Address(street: Option[List[Street]], state: Option[State])

If I understood method signatures right:
def bar(user, id): Option[UserInfo]
def baz(user, List[Street]): Future[BarId]
def get(id): Option[Bar]
You can implement your method something like this:
val streetsOpt: Option[List[Street]] = bar(user, id).flatMap(_.flatMap(_.address.flatMap(_.street)))
streetsOpt.flatMap(streets => {
baz(user, streets).map(_ => get(id))
}).getOrElse(successful(None)))

Just quickly looking at this, within this line:
baz(user, street).flatMap(_ => get(id))
I don't think that the last flatMap won't work properly because you seem to be passing in a function which is of a type something like:
f: => A
i.e. extracting the underlying value from some context, whereas flatMap expects you to unpack this value and then wrap in a new context, and so has type:
f: A => M[B]
When you are making the call to
get(id)
Shouldn't this be being applied to a map method instead, which expects a function of type:
f: A => B

There are a couple of ways of dealing with nested contexts like this. I gave a talk about three that I know: monad transformers (explicit, more "standard", but a bit more verbose), Kleisli (very elegant, if you're willing to write in pointfree style), or my scalaz-transfigure library (a bit immature, a bit less explicit, but very concise).

Related

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.

Dealing with Type Erasure with foldLeft [duplicate]

I've trying to sort a list by a future boolean.
I have a list of IDs and I need to query an external service to find out if there's contextual information behind them. The method I use to do this returns an optional future.
By using the partition method I hoped to create two lists of IDs, one with contextual information and one without.
The following answer on here provided a lot of help for this: Scala - sort based on Future result predicate
I now have an rough, untested method that looks like so,
val futureMatch = listOfIds.map( b => b.map{ j =>
getContext(j).map{ k =>
Map( j -> k)
}
}).map(Future.sequence(_)).flatMap(identity)
val partitionedList = futureMatch.map(_.partition{
case (k, Some(v)) => true
case _ => false
})
So as advised in the other question, I'm attempting to get all my answers at the same level, and then using Future.sequence and flatMap(identity) to flatten nested layers of futures.
The problem is this doesn't feel very efficient.
Ideally the successful list would have a signature of List[Map[String, String]] not List[Map[String, Option[String]] and the failed list would just be a list of Strings, so it'd only need to be one dimensional. As it currently stands I have two identical list signatures which have some redundancy. For example in the successful list, I know this is going exist so it doesn't need to be an option.
Any ideas how I could achieve this structure and produce two lists with different signatures or even if this is the most efficient way.
Thanks.
EDIT: Looking at the signature for partition it looks like I can only produce two lists of the same signature, so a different signature is probably too much to ask. I guess I can just flatten the list afterwards.
I found a suitable solution in the comments of the question I linked too.
val (matched, unmatched) =
finalMatch.foldLeft(List.empty[Map[String, String]], List.empty[String]) {
case ((matched, unmatched), p) => p match {
case m:Map[String, String] => (m :: matched, unmatched)
case s:String => (matched, s :: unmatched)
}
}
The only issue with this is it leads to type erasure. I've opened another question to discuss this issue.
Dealing with Type Erasure with foldLeft
Thanks all.

Scala Syntax: Syntactic sugar for converting a Function0 into function1?

Sorry for the nebulous title, I had a hard time to to formulate what I mean. For that reason, lets directly dive into the code:
def bar(b: Int => String) = b(23)
def foo(b: => String) = bar(_ => b)
foo("foo" + "bar")
I found a similar code in the play framework and was wondering what actually happens with that code. I tinkered a bit and figured that bar(_ => b) will just create a function1 with the required argument type (given by bars signature) and uses the given function0 to generate the return value, ignoring the actual parameter of the function1.
However, this is just me trying to figure out what happens, a more definitive answer would be way better for my understanding - and besides that I might be completely wrong.
You're sort of right, except that => String is not a Function0 - () => String is.
=> String is a call-by-name string. It'll be evaluated when it's referred to.
def foo(b: String) = bar(_ => b) would also get the job done, with the exception that b would be evaluated eagerly.

PartialFunction That Isn't Partial

Is there a reason to use a PartialFunction on a function that's not partial?
scala> val foo: PartialFunction[Int, Int] = {
| case x => x * 2
| }
foo: PartialFunction[Int,Int] = <function1>
foo is defined as a PartialFunction, but of course the case x will catch all input.
Is this simply bad code as the PartialFunction type indicates to the programmer that the function is undefined for certain inputs?
There is no advantage in using a PartialFunction instead of a Function, but if you have to pass a PartialFunction, then you have to pass a PartialFunction.
Note that, because of the inheritance between these two, overloading a method to accept both results in something difficult to use, as the type inference won't work.
The thing is, there are many examples of times when what you need to define on a trait/object/function definition is a PartialFunction but in reality the real implementation may not be one. Case in point, take a look at def collect[B](f: PartialFunction[A,B]):
val myList = thatList collect {
case Right(value) => value
case Left(other) => other.toInt
}
It's clearly not a "real" partial as it is defined for all input. That said, if I wanted to, I could just have the Right match.
However, if I were to have written collect as a full on plain function, then I'd miss out on the desired behavior (that is to be both a filter and a map rolled into one base on when a function is defined.) That's nice behavior and allows for a lot of flexibility when writing my own code.
So I guess the better question is, will you ever want behavior to reflect that a function might not be defined everywhere? If the answer is no, then don't do it.
PartialFunction literals allow pattern matching directly on arguments (e.g. { case (a, b) => ... } instead of _ match { case (a, b) => ... }), which makes code more readable (see #wheaties' answer for another example).
EDIT: apparently this is wrong, see Daniel C. Sobral's comment on his answer. Not deleting, so that the comments still make sense.

Get Option value or throw an exception

Given an Option, what is the idiomatic way to get its value or throw an exception trying?
def foo() : String = {
val x : Option[String] = ...
x.getOrException()
}
A throw "statement" is really an expression in Scala, and it has type Nothing, which is a subtype of every other type. This means you can just use plain old getOrElse:
def myGet[A](oa: Option[A]) = oa.getOrElse(throw new RuntimeException("Can't."))
You really, really shouldn't be doing this, though.
(EDIT: this is not the best or most idiomatic way to do it. I wrote it when I was not familiar with Scala. I leave it here for an example of how not to do it. Nowadays I would do as #TravisBrown)
I think it really boils down to two things:
how sure are you that the value is there?
how do you want to react if it isn't?
If at that point in your code you expect the value to be there, and in the remote case that it isn't you want your program to fail fast, then I would only do a normal get and let Scala throw a NoSuchElementException if there was no value:
def foo() : String = {
val x : Option[String] = ...
x.get
}
If you want to handle the case differently (throw your own exception) I think a more elegant way would look like this:
def foo(): String = {
val x: Option[String] = None
x match {
case Some(value) => value
case None => throw new MyRuntimeException("blah")
}
}
And of course if you want to supply your own alternative value for the case that the Option is None you would just use getOrElse:
def foo(): String = {
val x: Option[String] = None
x.getOrElse("my alternative value")
}
I hope this will help you to understand how to represent errors (and generally effects) using types.
Error handling strategies in functional Scala
Use Option to return optional values. For example - fail to find entity in storage.
Use Option(possiblyNull) to avoid instances of Some(null).
Use Either[Error, T] to report expected failure. For example - email format is wrong, cannot parse a string to a number, etc.
Model your errors as ADTs (simply speaking kind of type hierarchies) to use it, for example, on the Left of the Either to represent more complex error scenarios.
Throw Exception only to signal unexpected and not-recoverable failures. Like missing config file.
Use Either.catchOnly or Try or Cats.IO (advanced) rather than a catch block for handling unexpected failures. Hint: You can still use ADT but extend them from throwables. More about Either vs Try.
Use Validated data-type from Cats lib to accumulate errors rather than fail-fast (Either), but prefer Either's on module-level to simplify the composition of the program (to have the same types). For example - form data validation, parsing errors accumulation.
Use mentioned types and don't optimize program preemptively - since most probably, bottle-necks would be in business logic, not in effect types.
Such an approach will simplify maintenance and updates of your code since you can reason about it without going to implementation specifics (aka local-reasoning). Also - reduce bugs - you cannot miss an error in the type. And compose the program easier (with help of map, flatMap and other combinators) - since it's simpler on type level, rather than with non-local exceptions and side-effects.
More about learning functional Scala.
But be aware that sometimes with this approach types could stack up and it could become harder to compose things. Given, for example: x: Future[Either[Error, Option[T]]] What you can do:
Use map and flatMap in combination with pattern-matching to compose different values of such types, for example:
x.faltMap { case Right(Some(v)) => anotherFuture(v); case Left(er) => ... }
If it doesn't help you can try to use MonadTransformers (don't be scared of the name, it's just wrappers around the effect types like Either and Future)
Also, an option is to simplify your errors ADT by extending them from the Throwable to unify it with Future, then it'll be Future[Option[T]]
And finally, in your case one option will be:
def foo() : Either[Error, String] = {
val x : Option[String] = ...
x match {
case Some(v) => Right(v)
case None => Left(Error(reason))
}
}
Just use the .get method.
def get[T](o:Option[T]) = o.get
It will throw a NoSuchElementException if o is an instance of None.
Basically, I would work with options like this:
def addPrint(oi:Option[Int]) = oi.map(_+1).foreach(println)
addPrint(Some(41))
addPrint(Some(1336))
addPrint(None)
to avoid your specific question.
Scala now support this operation on maps using getOrElse() method, see documentation here
As pointed out already, throwing an exception in Scala is an expression as well.
So you can do the following:
myMap.getOrElse(myKey, throw new MyCustomException("Custom Message HERE")