我正在尝试从Option[Tuple]
创建连接,然后返回
结果是分离,但我的代码看起来有点奇怪:
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
}
}
我首先需要模仿匹配我的第一个Option
以检查我有
所有必需的选项,然后如果我这样做,尝试在Try
内连接
然后将try的结果转换为析取。
有没有更好的方法来进行这种转变?
答案 0 :(得分:6)
您可能希望将它们转换为相同的类型 - 您可以在.toRightDisjunction
上使用Option
,而您可以使用Try
执行scala.util.control.Exception
事件:
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
您还可以使用Option
而不是明确的.sequence
/ for
执行初始yield
事件(这可能需要shapeless-scalaz):
params = (config.mysqlHost, config.mysqlPort, ...).sequence
答案 1 :(得分:3)
scalaz.std包中包含
object option extends OptionInstances with OptionFunctions {
object optionSyntax extends scalaz.syntax.std.ToOptionOps with scalaz.syntax.std.ToOptionIdOps
}
Scalaz添加到scala.Option
的操作在OptionInstances
(类型类)和OptionsFunctions
中定义。 OptionFunctions
包含以下方法:
final def toRight[A, E](oa: Option[A])(e: => E): E \/ A = oa match {
case Some(a) => \/-(a)
case None => -\/(e)
}
final def toLeft[A, B](oa: Option[A])(b: => B): A \/ B = oa match {
case Some(a) => -\/(a)
case None => \/-(b)
}
语法和隐式转换在scalaz.syntax
包中提供,特别是OptionOps
是Scalaz“Rich Option”。 ToOptionOps
包含Option => OptionOps
如果正确导入optionSyntax,则可以编写以下内容
import scalaz.std.option.optionSyntax._
val disjunction = params.\/>(new Exception("Not enough parameters to initialize a ssh client"))
然后你可以从那里映射/ flatMap