如何在为空时保留 FlatMap 选项

How to FlatMap Option while Preserving When Empty

我想进行平面图选项转换,同时了解转换 "dropped out" 的位置(即首次返回 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
}

我想你想要的是一个 Either[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() 方法将 Option 转换为 Either:

Some(x).toRight(y) //x.right
None.toRight(y)    //y.left

虽然,事实上,使用 fold()getOrElse() 可能更容易和更清楚。

val reportFilteredCause :DomainObject => String = {
  stringFetcher(_).fold("Failed to fetch string representation"){
   filterer(_).getOrElse("Failed to filter field")
  }
}