Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

collapsing \/[A,A] to A

In a web application, I've got an action that can fail in various different ways, or eventually succeed.

In this context success and failure are represented by subclasses of SimpleResult (representing an HTTP response)

I use the monadic operations on scalaz / to encode my algorithm, with something like :

val result = for {
  user <- fetchUser \/> Forbidden("you must be connected to perform this action")
  basket <- user.basket \/> NotFound("no basket !")
  ...
} yield Ok(someBasketView(user, basket))

so this ends up to be a SimpleResult \/ SimpleResult and I have to write this :

 result fold (identity, identity)

to extract the result from the disjunction, which I find rather ugly.

Is there some abstraction that captures such "obviously-simplifiable-structure" ? or perhaps disjunction is not the right abstraction for that matter ?

like image 561
Valentin Kasas Avatar asked Mar 20 '23 06:03

Valentin Kasas


1 Answers

Both the standard library and Scalaz provide this operation as merge:

scala> val e: Either[String, String] = Right("a")
e: Either[String,String] = Right(a)

scala> e.merge
res0: String = a

And:

scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._

scala> val ez: String \/ String = "a".right
ez: scalaz.\/[String,String] = \/-(a)

scala> ez.merge
res1: String = a

Without knowing more about your SimpleResult it's hard to say whether this is a legitimate use of disjunction—usually you'd capture the information about whether the result is a failure or not in the constructors.

like image 70
Travis Brown Avatar answered Mar 24 '23 03:03

Travis Brown