Side effecting function returning disjunction - scala

I have a side effecting function which mutates class variable or Throw an exception if precondition isn't met. After adding into class level mutable Map I want to return a "boolean" from the function indicating a success. So below is what I am thinking about but hard-coding boolean to "true" feels inappropriate however that would be the case when it goes into yield block as otherwise left side of disjunction will be populated with an exception.
def add(e: Entity, value: String): \/[Throwable,Boolean] = {
checkIfFieldIsKey(e.id) match {
case Some(id) =>
val validId = validateIdType(..)
for {
k <- validId
} yield { keys += (e -> k); true }
case None =>
for {
r <- validateTypeAndValue(e, value)
} yield { values += (e -> value); true }
}
}
where 'keys' and 'values' are 'val' instances of ConcurrentHashMap. So every time 'add' is successful right side of disjunction will always be "true" meaning boolean value will never be false. does this look appropriate?

When a side-effecting method has no meaningful return value, you typically return Unit. If you want to capture the possibility of failure, it's perfectly reasonable to return Throwable \/ Unit, which is probably what I'd do here. In any case I'd say your intuition that it's a bad idea to return a Throwable \/ Boolean where the right side can never be anything but true is spot on.

It seems silly. It could be reduced to Option[Throwable] -- None if successful, or the exception if it wasn't. The only thing against it is that None isn't usually associated with success.
As an alternative, write your own maybe monad, with Success and Failure(throwable) as it's cases.

Related

Best way to write this conditional statements in scala

I have two objects of same type but I want to call methods using the objects but depending upon couple of boolean values.
def myMethod(a: Boolean, b: Boolean, obj1: MyClass, obj2: MyClass): Future[Done] = {
if(a) obj1.methodWhichReturnsFuture()
if(b) obj2.methodWhichReturnsFuture()
}
Here the method #methodWhichReturnsFuture has return typr Future[Done]. THis is showing error since I am returning Unit here. I though of creating a 'var' and assigning it inside both method call but looks like its not a good way. This is definitely basic but I want to know what is the better way to implement this? Thanks
In Scala, an if without an else can only be executed for side-effect, so the resulting value of
if (a) obj1.methodWhichReturnsFuture()
will be discarded and the singleton value for Unit (()) will be the result. The same will happen in the if (b) statement (and technically that () will be the result of myMethod, but it's the same () as from the if (a)).
You will thus need to add else clauses which also result in a Future[Done] and determine what you want the result to be if both a and b are true (furthermore, if you want both the obj1 and obj2 calls to be made, you will need to decide whether to execute them sequentially or in parallel) as well as if both a and b are false.
Thankfully, because Done is a singleton (it's basically the same as Unit as far as encoding "this happened", but in a way which is nicer for Java code using Akka), there's a reasonable default Future[Done]: Future.successful(Done) (which can basically be interpreted as "yeah, sure, I did it (but there was nothing to actually do)").
So if you want to do both the obj1 and obj2 calls simultaneously (or at least without a defined "happens-before" relationship), you could write:
val obj1Fut = if (a) obj1.methodWhichReturnsFuture() else Future.successful(Done)
val obj2Fut = if (b) obj2.methodWhichReturnsFuture() else Future.successful(Done)
// exploits eagerness of Future, won't complete until both obj1Fut and obj2Fut have completed
obj1Fut.flatMap(_ => obj2Fut)
If you don't want to perform the obj2 call until after the obj1 call:
val obj1Fut = if (a) obj1.methodWhichReturnsFuture() else Future.successful(Done)
obj1Fut.flatMap { _ =>
if (b) obj2.methodWhichReturnsFuture()
else Future.successful(Done)
}
Note that in the Unit returning code you presented, it's quite possible for the obj2 future to complete before obj1's future has completed.
And if you only wanted to do the obj1 call if both a and b were true:
if (a) obj1.methodWhichReturnsFuture()
else if (b) obj2.methodWhichReturnsFuture()
else Future.successful(Done)
// or the equivalent pattern match, which might be more legible than if else if else
// (a, b) match {
// case (true, _) => obj1.methodWhichReturnsFuture()
// case (false, true) => obj2.methodWhichReturnsFuture()
// case (false, false) => Future.successful(Done)
// }

How to graciously combine results from two Either's

I have a function in which I need to combine results from two Either objects.
I need the Right side of "request" if "handlingResult" is a Right, and it is a given fact that if "handlingResult" is a Right, "request" is also a Right.
If "handlingResult" is Left, I need its value to build a response.
Right now this is the implementation (both FailingResponse and SuccessfulResponse extend ValuationResponse):
def getResponse(handlingResult : Either[FailureReason, List[StockValuation]]
,request : Either[Error, ValuationRequest]
): ValuationResponse = {
handlingResult.fold(
failureReason =>
FailingResponse(failureReason.message
,failureReason.statusCode),
listOfValuations =>
SuccessfulResponse(listOfValuations
,request.right.get.symbol
,request.right.get.function
,StatusCodes.SUCCESS))
}
But I suspect that accessing an either directly is not a good practice, such as in
request.right.get.symbol
What would be a good way to achieve the same behavior but doing it in a recommendable way?
Either is right-biased in Scala 2.12 and up, so you can use a for-comprehension
def getResponse(handlingResult : Either[FailureReason, List[StockValuation]]
,request : Either[Error, ValuationRequest]
): ValuationResponse = {
val result = for {
result <- handlingResult
req <- request
} yield {
SuccessfulResponse(result, req.symbol, req.function, SUCCESS)
}
result match {
case Right(resp) => resp
case Left(FailureReason(msg, code)) => FailingResponse(msg, code)
case Left(Error) => FailingResponse("failed for unknown reasons", SOME_NEW_CODE)
}
}
Note that although you don't expect the last case statement to ever match, it should be there for completeness, and a new code, SOME_NEW_CODE can be made to indicate that something unexpected occurred.

having trouble composing Scala Future from multiple Futures of different types

I have two functions: one returns a Future[Thing Or Exception] and another that returns Future[Boolean. I want a function that calls both and returns Future[Thing Or Exception]. If the boolean function returns false I want to return an exception, else the return of the other function.
I have code like this but a) I hate the cast and b) when run on the "boolean gets true" path I get this error when I eventually Await.result on the return in my test code: "Promise$DefaultPromise cannot be cast to org.scalatic.Or".
def thingFuture: Future[Thing Or Exception]
def boolFuture: Future[Boolean]
def combineFutures: Future[Thing Or Exception] = {
val result = boolFuture.map {x =>
x match {
case true => thingFuture
case false => Exception
}
}
// without the cast compiler says result is of type Future[Object]
result.asInstanceOf[Future[Thing Or Exception]]
}
I've also tried this but it gets the same Promise error on the success path
def combineFutures: Future[Thing Or Exception] = {
val result = boolFuture.map {x =>
x match {
case true => thingFuture.map { y =>
y match {
case Good(thing) => thing
case Bad(exception) => exception
}
case false => Exception
}
}
}
Can anyone tell me how to compose two futures with different return types? Thanks!
Every future can be completed with failed state in case exception has occurred, so you can simply return thingFuture in the "happy path" and throw an exception in case boolean is false. This will return a Future.failed with the underlying exception.
val result = boolFuture.flatMap {x =>
x match {
case true => thingFuture
case false => throw new Exception("whatever")
}
}
Note the flatMap instead of map. Because we map the underlying value of one future into a yet another future, by using simple map we would wind up with Future[Future[Thing]].
Also note that instead of throwing an exception, you could also return a Future.failed(throw new Exception("whatever")) and the result would be the same - in both case you get a failed future.
EDIT: I just realized Or comes from scalactic, which I never used, but the philosophy remains the same. You need to flatMap your boolean future and your ThingOrException future in order to wind up with Future[ThingOrException]. If you ever find yourself in a situation where you need to flatMap a Future, but one of the case clauses returns an ordinary value (e.g. in case of true return Future[Thing], in case of false return just Exception) then you can wrap the ordinary value into a future. This way all branches return a future and flatMap will work correctly. For example:
val someOtherFuture = Future(43)
val someOrdinaryValue = 44
Future(someInteger).flatMap {
case 42 => someOtherFuture
case _ => Future(someOrdinaryValue)
}
In order to simplify things for the runtime machinery a bit, you can also write Future.successful(someOrdinaryValue) in which case no background computation is started.
As far as I can tell from Scalatic documentation, you can get an instance of Right Or Left by either Good(Right) or Bad(Left).
That means the composition can potentially look like this:
boolFuture.flatMap(b => if (b) thingFuture else Future.successful(Bad(new Exception())))
The types should unify to Future[Or[Thing, Exception]]

How does Scala implement return from within an expression?

For example, if we have a method like
def find[A](xs: Seq[A], p: A => Boolean): Option[A] = {
xs.foreach(x => if (p(x)) return Some(x));
None;
}
(of course there is a library function for this, this is just an example). How does the execution escape foreach when the inner function returns?
Or in
def foo(x: AnyRef): String =
process(x match {
case (s: String) => s;
case _ => return "";
})
how does the execution avoid running process when return "" is issued?
The foo example depends on which of
def process(s: String): String
def process(s: => String): String
it is. I'm assuming the former, since you suggest process isn't run. This is just the way it always works when passing an argument--you do the argument-creation work first, then call the method. Since you run into a return, it's easy: you just call the appropriate return from bytecode while creating the argument*, and never go on to invoke the method. So it is just a local return.
The find example is a little more involved. Let's try a maximally simple example motivated by a foo which requires a nonlocal return:
class Nonlocal {
def pr(s: => String) = { println(s); "Printed" }
def foo(x: AnyRef): String = pr(x match {
case (s: String) => s;
case _ => return "";
})
}
The body of foo is equivalent to
import scala.runtime.NonLocalReturnControl
val temp = new AnyRef
try {
pr(x match {
case s: String => s
case _ => throw new NonLocalReturnControl(temp, "")
})
}
catch {
case nlrc: NonLocalReturnControl[_] if (nlrc.key eq temp) =>
nlrc.value.asInstanceOf[String]
}
The key things to notice is that a sentinel object is created so that these things can be arbitrarily nested without clobbering each other, and that NonLocalReturnControl carries the correct value back. Unsurprisingly, this isn't exactly cheap compared to just returning, say, an Int. But since it creates an exception without a stack trace (safe, because it can't escape: the catch block is guaranteed to catch it), it's not that bad--is about as bad as calling a trig function or summing an array with a few dozen entries.
Note also that pr only gets partly executed before the exception gets it. In this case, it doesn't print anything because the first thing it does is try to use s to fill in an actual string, but then it hits the exception which drops control back to foo. (So you get an empty string back from foo, but you don't print anything.)
* Actually, in bytecode it tends to be a jump to the end of the method, with the load/return there. Irrelevant conceptually, though.

Processing Scala Option[T]

I have a Scala Option[T]. If the value is Some(x) I want to process it with a a process that does not return a value (Unit), but if it is None, I want to print an error.
I can use the following code to do this, but I understand that the more idiomatic way is to treat the Option[T] as a sequence and use map, foreach, etc. How do I do this?
opt match {
case Some(x) => // process x with no return value, e.g. write x to a file
case None => // print error message
}
I think explicit pattern matching suits your use case best.
Scala's Option is, sadly, missing a method to do exactly this. I add one:
class OptionWrapper[A](o: Option[A]) {
def fold[Z](default: => Z)(action: A => Z) = o.map(action).getOrElse(default)
}
implicit def option_has_utility[A](o: Option[A]) = new OptionWrapper(o)
which has the slightly nicer (in my view) usage
op.fold{ println("Empty!") }{ x => doStuffWith(x) }
You can see from how it's defined that map/getOrElse can be used instead of pattern matching.
Alternatively, Either already has a fold method. So you can
op.toRight(()).fold{ _ => println("Empty!") }{ x => doStuffWith(x) }
but this is a little clumsy given that you have to provide the left value (here (), i.e. Unit) and then define a function on that, rather than just stating what you want to happen on None.
The pattern match isn't bad either, especially for longer blocks of code. For short ones, the overhead of the match starts getting in the way of the point. For example:
op.fold{ printError }{ saveUserInput }
has a lot less syntactic overhead than
op match {
case Some(x) => saveUserInput(x)
case None => printError
}
and therefore, once you expect it, is a lot easier to comprehend.
I'd recommend to simply and safely use opt.get which itself throws a NoSuchElementException exception if opt is None. Or if you want to throw your own exception, you can do this:
val x = opt.getOrElse(throw new Exception("Your error message"))
// x is of type T
as #missingfaktor says, you are in the exact scenario where pattern matching is giving the most readable results.
If Option has a value you want to do something, if not you want to do something else.
While there are various ways to use map and other functional constructs on Option types, they are generally useful when:
you want to use the Some case and ignore the None case e.g. in your case
opt.map(writeToFile(_)) //(...if None just do nothing)
or you want to chain the operations on more than one option and give a result only when all of them are Some. For instance, one way of doing this is:
val concatThreeOptions =
for {
n1 <- opt1
n2 <- opt2
n3 <- opt3
} yield n1 + n2 + n3 // this will be None if any of the three is None
// we will either write them all to a file or none of them
but none of these seem to be your case
Pattern matching is the best choice here.
However, if you want to treat Option as a sequence and to map over it, you can do it, because Unit is a value:
opt map { v =>
println(v) // process v (result type is Unit)
} getOrElse {
println("error")
}
By the way, printing an error is some kind of "anti-pattern", so it's better to throw an exception anyway:
opt.getOrElse(throw new SomeException)