如何在保留空时保留FlatMap选项

时间:2018-04-04 18:11:30

标签: scala functional-programming optional either

我想平面化选项转换,同时可以看到转换“退出”的位置(即首次返回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")
}

理想情况下,我想写下面的内容,在其中传递与每个Option转换相关联的报告字符串:

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
}

1 个答案:

答案 0 :(得分:3)

我认为你想要的是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")
  }
}