Ral*_*lph 1 monads scala either
我有一个case class包含命令行配置信息的Scala :
case class Config(emailAddress: Option[String],
firstName: Option[String]
lastName: Option[String]
password: Option[String])
Run Code Online (Sandbox Code Playgroud)
我正在编写一个验证函数来检查每个值是否为Some:
def validateConfig(config: Config): Try[Config] = {
if (config.emailAddress.isEmpty) {
Failure(new IllegalArgumentException("Email Address")
} else if (config.firstName.isEmpty) {
Failure(new IllegalArgumentException("First Name")
} else if (config.lastName.isEmpty) {
Failure(new IllegalArgumentException("Last Name")
} else if (config.password.isEmpty) {
Failure(new IllegalArgumentException("Password")
} else {
Success(config)
}
}
Run Code Online (Sandbox Code Playgroud)
但如果我理解来自Haskell的monad,似乎我应该能够将验证链接在一起(伪语法):
def validateConfig(config: Config): Try[Config] = {
config.emailAddress.map(Success(config)).
getOrElse(Failure(new IllegalArgumentException("Email Address")) >>
config.firstName.map(Success(config)).
getOrElse(Failure(new IllegalArgumentException("First Name")) >>
config.lastName.map(Success(config)).
getOrElse(Failure(new IllegalArgumentException("Last Name")) >>
config.password.map(Success(config)).
getOrElse(Failure(new IllegalArgumentException("Password"))
}
Run Code Online (Sandbox Code Playgroud)
如果任何config.XXX表达式返回Failure,则整个thing(validateConfig)应该失败,否则Success(config)应该返回.
有没有办法用这个Try,或者其他一些类?
将每个转换Option为正确投影的实例非常简单Either:
def validateConfig(config: Config): Either[String, Config] = for {
_ <- config.emailAddress.toRight("Email Address").right
_ <- config.firstName.toRight("First Name").right
_ <- config.lastName.toRight("Last Name").right
_ <- config.password.toRight("Password").right
} yield config
Run Code Online (Sandbox Code Playgroud)
Either 在标准库的术语中,它不是monad,但它的正确投影是,并且将在失败的情况下提供您想要的行为.
如果你最喜欢a Try,你可以转换结果Either:
import scala.util._
val validate: Config => Try[Config] = (validateConfig _) andThen (
_.fold(msg => Failure(new IllegalArgumentException(msg)), Success(_))
)
Run Code Online (Sandbox Code Playgroud)
我希望标准库提供了一种更好的方法来进行这种转换,但事实并非如此.
| 归档时间: |
|
| 查看次数: |
1132 次 |
| 最近记录: |