Scala 如何在空时保留FlatMap选项
我希望对选项转换进行平面映射,同时可以看到转换“退出”的位置(即,首先返回Scala 如何在空时保留FlatMap选项,scala,functional-programming,optional,either,Scala,Functional Programming,Optional,Either,我希望对选项转换进行平面映射,同时可以看到转换“退出”的位置(即,首先返回None) 一些示例代码: val stringFetcher : DomainObject=>Option[String] = ... val filterer : String=>Option[String] = ... val reportFilteredCause: DomainObject => String = do => { val strOption = stringFet
None
)
一些示例代码:
val stringFetcher : DomainObject=>Option[String] = ...
val filterer : String=>Option[String] = ...
val reportFilteredCause: DomainObject => String = do =>
{
val strOption = stringFetcher(do)
val filterReasonOption = strOption flatMap filterer
filterReasonOption.getOrElse("Failed to fetch string representation OR field not filtered")
}
理想情况下,我希望编写如下内容,其中我传入一些与每个选项转换相关的报告字符串:
val stringFetcher : DomainObject=>Option[String] = ...
val filterer : String=>Option[String] = ...
val reportFilteredCause: DomainObject => String = do =>
{
val strOption : Either[Option[String], String]] = EitherWrapper stringFetcher(do) "Failed to fetch string representation"
val filterReasonOption = strOption flatMapWrapper filterer "Failed to filter field
filterReasonOption
}
我认为您需要的是一个
或[String,String]
,其中左投影是失败消息,右投影是结果字符串
val reportFilteredCause :DomainObject => String = { dob :DomainObject =>
val strOption :Either[String, String] =
stringFetcher(dob).toRight("Failed to fetch string representation")
val filterReasonOption :Either[String,String] =
strOption.flatMap(filterer(_).toRight("Failed to filter field"))
filterReasonOption.fold(identity,identity)
}
.toRight()
方法将选项
转换为选项
:
Some(x).toRight(y) //x.right
None.toRight(y) //y.left
尽管事实上,使用fold()
和getOrElse()
可能更容易、更清晰
stringFetcher
和getStringRepr
之间的关系是什么?看起来他们做了同样的事情。为什么一个已定义但未使用,而另一个已使用但未定义?stringFetcher
和filterer
只是我想应用于DomainObject
的两个操作(按各自的顺序!)。我把…
放在定义的地方-它们应该被使用和定义。请阅读我的问题(和您的代码)。为什么定义了stringFetcher
但从未使用过?为什么代码中使用了getStringRepr
,但从未定义?已修复;)非常感谢。
val reportFilteredCause :DomainObject => String = {
stringFetcher(_).fold("Failed to fetch string representation"){
filterer(_).getOrElse("Failed to filter field")
}
}