Higher order functional approach to short circuit the execution and execute block of code if disjunction has right value - scala

I have following def.
def withAuthorized[T,U](t:T)(func: T => U) : U = func(t)
Usage of it is
withAuthorized(methodReturningDisjunction){ res : \/[Throwable,Boolean] =>
res match{
case \/-(r) => { block of code }
case -\/(e) => e.left
}
where methodReturningDisjunction returns \/[Throwable,Boolean]
I want to abstract out res pattern matching logic into withAuthorized method such that it'll accept block of code and execute only if first def (methodReturningDisjunction) returns right side of disjunction. I am wondering what modifications will have to made to withAuthorized to make it function that way?

What you are looking for is the map method on \/:
def withAuthorized[E,T,U](res:\/[E,T])(func: T => U) : \/[E,U] = res.map(func)

Related

How to check if function is partial in Scala?

I have a method that receives a function, but that function may be partial, in such case I don't want it to fail with MatchError.
def doSomething[X,Y](opt:Option[X])(f:X=>Y)={
f match {
case p:PartialFunction[X,Y]=> opt.flatMap(p.lift) //This doesn't seem to work
case _ => opt.map(f)
}
}
That way I can use the method like this
doSomething(x){
case t if predicate(t) => otherMethod(t)
}
so in case I don't have a predicate, I can use it like
this doSomething(x)(otherMethod) instead of
doSoemthing(x){
case t=> otherMethod(t)
}
Note: Looking for a solution that doesn't require catching MatchError exceptions
This isn't an answer because I don't think that what you want is possible in Scala.
The original method is fine and works as expected, though it could be a bit simpler:
def doSomething[X, Y](opt: Option[X])(f: X => Y): Option[Y] = {
f match {
case p: PartialFunction[X, Y] => opt.collect(p)
case _ => opt.map(f)
}
}
The problem is here:
doSomething(x){
case t if predicate(t) => otherMethod(t)
}
Scala is creating a Function rather than a PartialFunction from that match expression so the test is failing. If you pass a real PartialFunction the method works OK.
val p: PartialFunction[Int, Int] = {
case i: Int if i > 0 => i
}
doSomething(Some(0))(p) // Returns None
I don't think there is any way of doing what you want, mainly because doSomething has multiple argument lists which messes up type deduction for the second argument list.
My suggestion is just to use
x.map(f)
or
x.collect{
case ...
}
as appropriate in the calling code.
The syntax for partial function has been changed since 2.9 per SLS 8.5, so that even you do { case x => y}, it DOES NOT mean it is a partial function. Its type will be exact as you define it as.
In your case, you defined it as X=>Y (as in your function parameter), so it is just a X=>Y (it got compiled into a regular function, and non match cases will throw MatchError), and even you do isInstanceOf[PartialFunciton[_,_]], it won't match.
To make your scenario work, you can just simply cast the passed function as PartialFunction, like:
doSomething(Some(1))({case 2 => 0}: PartialFunction[Int,Int]) //This returns None without MatchError
while
doSomething(Some(1)){case 2 => 0} //This gives MatchError and it is not recognized as PartialFunction inside the body
This is probably not as convenient as you thought it is, but it is the only way to make it work. (or you define 2 separate functions for either case, like collect and map in standard library)
I'm not sure what you are passing as a Partial Function, but definitely you should have to define it with specific signature like this:
val positive: PartialFunction[Int, Option[Int]] = {
case x if x >= 0 => Some(x)
case _ => None
The positive function is defined only for positive numbers. In case of negative numbers, the function returns None and you won't get scala.MatchError in runtime.
This specific function enables you to access to isDefinedAt method which is testing dynamically if a value is in the domain of the function.
postive(5).isDefinedAt // true
poistive.isInstanceOf[PartialFunction[Int, Option[Int]]] // true
I demonstrated here why you are always getting false when you check p.isInstanceOf
def doSomething[X,Y](opt:Option[X])(f:X=>Y)={
f match {
case p if p.isInstanceOf[PartialFunction[X,Y]] =>
println("I'm a pf")
println(s"Is it PartialFunction: ${p.isInstanceOf[PartialFunction[X,Y]]}")
opt.map(p)
case _ =>
println("I'm not a pf")
opt.map(f)
}
}
doSomething[Int, Option[Int]](Some(5))(positive) // partial function case
doSomething[Int, String](Some(5)) { // tricky case
case s => s.toString
}
You can play with it here:

Composing a sequence of functions that return future

I am looking for an elegant way of composing a sequence of functions that return Future. I.e., for a sequence of (f1, f2, ..., f_n), each function being of type T=>Future[T], I want to produce a new function, g, where g(x) = f_n(...f2(f1(x))...).
My implementation is as follows:
def doInOrder[T] (fs : (T => Future[T])*)(implicit ec:ExecutionContext): T=>Future[T] = {
(t:T) => {
fs.reduceLeft((future1: T=>Future[T], future2: T=>Future[T]) =>
(arg:T) => future1(arg).flatMap((arg2:T) => future2(arg2))
)(t)
}
}
This works, as far as I can tell. The solution seems a little convoluted though, with a number of nested lambdas. Can it be simplified?
The problem comes from Horstmann's book, Scala for the impatient, which asks to
Write a function doInOrder that, given two functions f: T =>
Future[U] and g: U
=> Future[V], produces a function T => Future[U] that, for a given t, eventually yields g(f(t))
and then to:
Repeat the preceding exercise for any sequence of functions of type T
=> Future[T].
How about this?
def doInOrder[T] (fs : (T => Future[T])*)(implicit ec:ExecutionContext): T=>Future[T] = {
t => fs.foldLeft(Future.successful(t))((acc, f) => acc.flatMap(f))
}

Continuation-passing style in Scala

I have superficially read a couple of blog articles/Wikipedia about continuation-passing style. My high-level goal is to find a systematic technique to make any recursive function (or, if there are restrictions, being aware of them) tail-recursive. However, I have trouble articulating my thoughts and I'm not sure if what my attempts of it make any sense.
For the purpose of the example, I'll propose a simple problem. The goal is, given a sorted list of unique characters, to output all possible words made out of these characters in alphabetical order. For example, sol("op".toList, 3) should return ooo,oop,opo,opp,poo,pop,ppo,ppp.
My recursive solution is the following:
def sol(chars: List[Char], n: Int) = {
def recSol(n: Int): List[List[Char]] = (chars, n) match {
case (_ , 0) => List(Nil)
case (Nil, _) => Nil
case (_ , _) =>
val tail = recSol(n - 1)
chars.map(ch => tail.map(ch :: _)).fold(Nil)(_ ::: _)
}
recSol(n).map(_.mkString).mkString(",")
}
I did try to rewrite this by adding a function as a parameter but I did not manage to make something I was convinced to be tail-recursive. I prefer not including my attempt(s) in the question as I'm ashamed of their naiveness, so please excuse me for this.
Therefore the question is basically: how would the function above be written in CPS ?
Try that:
import scala.annotation.tailrec
def sol(chars: List[Char], n: Int) = {
#tailrec
def recSol(n: Int)(cont: (List[List[Char]]) => List[List[Char]]): List[List[Char]] = (chars, n) match {
case (_ , 0) => cont(List(Nil))
case (Nil, _) => cont(Nil)
case (_ , _) =>
recSol(n-1){ tail =>
cont(chars.map(ch => tail.map(ch :: _)).fold(Nil)(_ ::: _))
}
}
recSol(n)(identity).map(_.mkString).mkString(",")
}
The first order of business in performing the CPS transform is deciding on a representation for continuations. We can think of continuations as a suspended computation with a "hole". When the hole is filled in with a value, the remainder of the computation can be computed. So functions are a natural choice for representing continuations, at least for toy examples:
type Cont[Hole,Result] = Hole => Result
Here Hole represents the type of the hole that needs to be filled in, and Result represents the type of value the computation ultimately computes.
Now that we have a way to represent continuations, we can worry about the CPS transform itself. Basically, this involves the following steps:
The transformation is applied recursively to an expression, stopping at "trivial" expressions / function calls. In this context, "trivial" includes functions defined by Scala (since they are not CPS-transformed, and thus do not have a continuation parameter).
We need to add a parameter of type Cont[Return,Result] to each function, where Return is the return type of the untransformed function and Result is the type of the ultimate result of the computation as a whole. This new parameter represents the current continuation. The return type for the transformed function is also changed to Result.
Every function call needs to be transformed to accommodate the new continuation parameter. Everything after the call needs to be put into a continuation function, which is then added to the parameter list.
For example, a function:
def f(x : Int) : Int = x + 1
becomes:
def fCps[Result](x : Int)(k : Cont[Int,Result]) : Result = k(x + 1)
and
def g(x : Int) : Int = 2 * f(x)
becomes:
def gCps[Result](x : Int)(k : Cont[Int,Result]) : Result = {
fCps(x)(y => k(2 * y))
}
Now gCps(5) returns (via currying) a function that represents a partial computation. We can extract the value from this partial computation and use it by supplying a continuation function. For example, we can use the identity function to extract the value unchanged:
gCps(5)(x => x)
// 12
Or, we can print it by using println instead:
gCps(5)(println)
// prints 12
Applying this to your code, we obtain:
def solCps[Result](chars : List[Char], n : Int)(k : Cont[String, Result]) : Result = {
#scala.annotation.tailrec
def recSol[Result](n : Int)(k : Cont[List[List[Char]], Result]) : Result = (chars, n) match {
case (_ , 0) => k(List(Nil))
case (Nil, _) => k(Nil)
case (_ , _) =>
recSol(n - 1)(tail =>
k(chars.map(ch => tail.map(ch :: _)).fold(Nil)(_ ::: _)))
}
recSol(n)(result =>
k(result.map(_.mkString).mkString(",")))
}
As you can see, although recSol is now tail-recursive, it comes with the cost of building a more complex continuation at each iteration. So all we've really done is trade space on the JVM's control stack for space on the heap -- the CPS transform does not magically reduce the space complexity of an algorithm.
Also, recSol is only tail-recursive because the recursive call to recSol happens to be the first (non-trivial) expression recSol performs. In general, though, recursive calls would be take place inside a continuation. In the case where there is one recursive call, we can work around that by transforming only calls to the recursive function to CPS. Even so, in general, we would still just be trading stack space for heap space.

Avoiding deeply nested Option cascades in Scala

Say I have three database access functions foo, bar, and baz that can each return Option[A] where A is some model class, and the calls depend on each other.
I would like to call the functions sequentially and in each case, return an appropriate error message if the value is not found (None).
My current code looks like this:
Input is a URL: /x/:xID/y/:yID/z/:zID
foo(xID) match {
case None => Left(s"$xID is not a valid id")
case Some(x) =>
bar(yID) match {
case None => Left(s"$yID is not a valid id")
case Some(y) =>
baz(zID) match {
case None => Left(s"$zID is not a valid id")
case Some(z) => Right(process(x, y, z))
}
}
}
As can be seen, the code is badly nested.
If instead, I use a for comprehension, I cannot give specific error messages, because I do not know which step failed:
(for {
x <- foo(xID)
y <- bar(yID)
z <- baz(zID)
} yield {
Right(process(x, y, z))
}).getOrElse(Left("One of the IDs was invalid, but we do not know which one"))
If I use map and getOrElse, I end up with code almost as nested as the first example.
Is these some better way to structure this to avoid the nesting while allowing specific error messages?
You can get your for loop working by using right projections.
def ckErr[A](id: String, f: String => Option[A]) = (f(id) match {
case None => Left(s"$id is not a valid id")
case Some(a) => Right(a)
}).right
for {
x <- ckErr(xID, foo)
y <- ckErr(yID, bar)
z <- ckErr(zID, baz)
} yield process(x,y,z)
This is still a little clumsy, but it has the advantage of being part of the standard library.
Exceptions are another way to go, but they slow things down a lot if the failure cases are common. I'd only use that if failure was truly exceptional.
It's also possible to use non-local returns, but it's kind of awkward for this particular setup. I think right projections of Either are the way to go. If you really like working this way but dislike putting .right all over the place, there are various places you can find a "right-biased Either" which will act like the right projection by default (e.g. ScalaUtils, Scalaz, etc.).
Instead of using an Option I would instead use a Try. That way you have the Monadic composition that you'd like mixed with the ability to retain the error.
def myDBAccess(..args..) =
thingThatDoesStuff(args) match{
case Some(x) => Success(x)
case None => Failure(new IdError(args))
}
I'm assuming in the above that you don't actually control the functions and can't refactor them to give you a non-Option. If you did, then simply substitute Try.
I know this question was answered some time back, but I wanted to give an alternative to the accepted answer.
Given that, in your example, the three Options are independent, you can treat them as Applicative Functors and use ValidatedNel from Cats to simplify and aggregate the handling of the unhappy path.
Given the code:
import cats.data.Validated.{invalidNel, valid}
def checkOption[B, T](t : Option[T])(ifNone : => B) : ValidatedNel[B, T] = t match {
case None => invalidNel(ifNone)
case Some(x) => valid(x)
def processUnwrappedData(a : Int, b : String, c : Boolean) : String = ???
val o1 : Option[Int] = ???
val o2 : Option[String] = ???
val o3 : Option[Boolean] = ???
You can then replicate obtain what you want with:
//import cats.syntax.cartesian._
(
checkOption(o1)(s"First option is not None") |#|
checkOption(o2)(s"Second option is not None") |#|
checkOption(o3)(s"Third option is not None")
) map (processUnwrappedData)
This approach will allow you to aggregate failures, which was not possible in your solution (as using for-comprehensions enforces sequential evaluation). More examples and documentation can be found here and here.
Finally this solution uses Cats Validated but could easily be translated to Scalaz Validation
I came up with this solution (based on #Rex's solution and his comments):
def ifTrue[A](boolean: Boolean)(isFalse: => A): RightProjection[A, Unit.type] =
Either.cond(boolean, Unit, isFalse).right
def none[A](option: Option[_])(isSome: => A): RightProjection[A, Unit.type] =
Either.cond(option.isEmpty, Unit, isSome).right
def some[A, B](option: Option[A])(ifNone: => B): RightProjection[B, A] =
option.toRight(ifNone).right
They do the following:
ifTrue is used when a function returns a Boolean, with true being the "success" case (e.g.: isAllowed(userId)). It actually returns Unit so should be used as _ <- ifTrue(...) { error } in a for comprehension.
none is used when a function returns an Option with None being the "success" case (e.g.: findUser(email) for creating accounts with unique email addresses). It actually returns Unit so should be used as _ <- none(...) { error } in a for comprehension.
some is used when a function returns an Option with Some() being the "success" case (e.g.: findUser(userId) for a GET /users/userId). It returns the contents of the Some: user <- some(findUser(userId)) { s"user $userId not found" }.
They are used in a for comprehension:
for {
x <- some(foo(xID)) { s"$xID is not a valid id" }
y <- some(bar(yID)) { s"$yID is not a valid id" }
z <- some(baz(zID)) { s"$zID is not a valid id" }
} yield {
process(x, y, z)
}
This returns an Either[String, X] where the String is an error message and the X is the result of calling process.

Implementing ifTrue, ifFalse, ifSome, ifNone, etc. in Scala to avoid if(...) and simple pattern matching

In Scala, I have progressively lost my Java/C habit of thinking in a control-flow oriented way, and got used to go ahead and get the object I'm interested in first, and then usually apply something like a match or a map() or foreach() for collections. I like it a lot, since it now feels like a more natural and more to-the-point way of structuring my code.
Little by little, I've wished I could program the same way for conditions; i.e., obtain a Boolean value first, and then match it to do various things. A full-blown match, however, does seem a bit overkill for this task.
Compare:
obj.isSomethingValid match {
case true => doX
case false => doY
}
vs. what I would write with style closer to Java:
if (obj.isSomethingValid)
doX
else
doY
Then I remembered Smalltalk's ifTrue: and ifFalse: messages (and variants thereof). Would it be possible to write something like this in Scala?
obj.isSomethingValid ifTrue doX else doY
with variants:
val v = obj.isSomethingValid ifTrue someVal else someOtherVal
// with side effects
obj.isSomethingValid ifFalse {
numInvalid += 1
println("not valid")
}
Furthermore, could this style be made available to simple, two-state types like Option? I know the more idiomatic way to use Option is to treat it as a collection and call filter(), map(), exists() on it, but often, at the end, I find that I want to perform some doX if it is defined, and some doY if it isn't. Something like:
val ok = resultOpt ifSome { result =>
println("Obtained: " + result)
updateUIWith(result) // returns Boolean
} else {
numInvalid += 1
println("missing end result")
false
}
To me, this (still?) looks better than a full-blown match.
I am providing a base implementation I came up with; general comments on this style/technique and/or better implementations are welcome!
First: we probably cannot reuse else, as it is a keyword, and using the backticks to force it to be seen as an identifier is rather ugly, so I'll use otherwise instead.
Here's an implementation attempt. First, use the pimp-my-library pattern to add ifTrue and ifFalse to Boolean. They are parametrized on the return type R and accept a single by-name parameter, which should be evaluated if the specified condition is realized. But in doing so, we must allow for an otherwise call. So we return a new object called Otherwise0 (why 0 is explained later), which stores a possible intermediate result as a Option[R]. It is defined if the current condition (ifTrue or ifFalse) is realized, and is empty otherwise.
class BooleanWrapper(b: Boolean) {
def ifTrue[R](f: => R) = new Otherwise0[R](if (b) Some(f) else None)
def ifFalse[R](f: => R) = new Otherwise0[R](if (b) None else Some(f))
}
implicit def extendBoolean(b: Boolean): BooleanWrapper = new BooleanWrapper(b)
For now, this works and lets me write
someTest ifTrue {
println("OK")
}
But, without the following otherwise clause, it cannot return a value of type R, of course. So here's the definition of Otherwise0:
class Otherwise0[R](intermediateResult: Option[R]) {
def otherwise[S >: R](f: => S) = intermediateResult.getOrElse(f)
def apply[S >: R](f: => S) = otherwise(f)
}
It evaluates its passed named argument if and only if the intermediate result it got from the preceding ifTrue or ifFalse is undefined, which is exactly what is wanted. The type parametrization [S >: R] has the effect that S is inferred to be the most specific common supertype of the actual type of the named parameters, such that for instance, r in this snippet has an inferred type Fruit:
class Fruit
class Apple extends Fruit
class Orange extends Fruit
val r = someTest ifTrue {
new Apple
} otherwise {
new Orange
}
The apply() alias even allows you to skip the otherwise method name altogether for short chunks of code:
someTest.ifTrue(10).otherwise(3)
// equivalently:
someTest.ifTrue(10)(3)
Finally, here's the corresponding pimp for Option:
class OptionExt[A](option: Option[A]) {
def ifNone[R](f: => R) = new Otherwise1(option match {
case None => Some(f)
case Some(_) => None
}, option.get)
def ifSome[R](f: A => R) = new Otherwise0(option match {
case Some(value) => Some(f(value))
case None => None
})
}
implicit def extendOption[A](opt: Option[A]): OptionExt[A] = new OptionExt[A](opt)
class Otherwise1[R, A1](intermediateResult: Option[R], arg1: => A1) {
def otherwise[S >: R](f: A1 => S) = intermediateResult.getOrElse(f(arg1))
def apply[S >: R](f: A1 => S) = otherwise(f)
}
Note that we now also need Otherwise1 so that we can conveniently passed the unwrapped value not only to the ifSome function argument, but also to the function argument of an otherwise following an ifNone.
You may be looking at the problem too specifically. You would probably be better off with the pipe operator:
class Piping[A](a: A) { def |>[B](f: A => B) = f(a) }
implicit def pipe_everything[A](a: A) = new Piping(a)
Now you can
("fish".length > 5) |> (if (_) println("Hi") else println("Ho"))
which, admittedly, is not quite as elegant as what you're trying to achieve, but it has the great advantage of being amazingly versatile--any time you want to put an argument first (not just with booleans), you can use it.
Also, you already can use options the way you want:
Option("fish").filter(_.length > 5).
map (_ => println("Hi")).
getOrElse(println("Ho"))
Just because these things could take a return value doesn't mean you have to avoid them. It does take a little getting used to the syntax; this may be a valid reason to create your own implicits. But the core functionality is there. (If you do create your own, consider fold[B](f: A => B)(g: => B) instead; once you're used to it the lack of the intervening keyword is actually rather nice.)
Edit: Although the |> notation for pipe is somewhat standard, I actually prefer use as the method name, because then def reuse[B,C](f: A => B)(g: (A,B) => C) = g(a,f(a)) seems more natural.
Why don't just use it like this:
val idiomaticVariable = if (condition) {
firstExpression
} else {
secondExpression
}
?
IMO, its very idiomatic! :)