I am trying to create a connection from an Option[Tuple], and return
the result in a disjunction, but my code looks a bit weird:
  def ssh(config: GushConfig): \/[Throwable, Client] = {
    val params = for {
      host <- config.mysqlHost
      port <- config.mysqlPort
      user <- config.mysqlUser
      password <- config.mysqlPassword
      sshAddress <- config.sshTunnelAddress
      sshTunnelUser <- config.sshTunnelUser
    } yield (host, port, user, password, sshAddress, sshTunnelUser)
    params match {
      case Some((host, port, user, password, sshAddress, sshTunnelUser)) ⇒
        Try({
          // Do stuff that can fail and throw exceptions
          new Client("127.0.0.1", lport, user, password)
        }) match {
          case Success(v) ⇒ v.right
          case Failure(t) ⇒ t.left
        }
      case None ⇒
        new Exception("Not enough parameters to initialize a ssh client").left
    }
  }
I first need to pattern match my first Option to check that I have
all required options, and then if I do, try to connect inside a Try
and then convert the result of the try into a disjunction.
Is there a nicer way to do this transformation?
You probably want to convert them both to the same type - you can use .toRightDisjunction on the Option, and you can do the Try thing using scala.util.control.Exception instead:
import scala.util.control.Exception._
for {
  params_ ← params.toRightDisjunction(
    new Exception("Not enough parameters to initialize a ssh client"))
  (host, port, user, password, sshAddress, sshTunnelUser) = params_
  v ← catching(classOf[Exception]) either functionThatCouldThrow() disjunction
} yield v
You could also do the initial Option thing using .sequence rather than an explicit for/yield (this might require shapeless-scalaz):
params = (config.mysqlHost, config.mysqlPort, ...).sequence
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With