Reputation: 257
I would like to flatmap option transformations, while having visibility into where the transformation "dropped out" (that is, where a None
is first returned).
Some sample code:
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")
}
Ideally, I'd like to write something like below, where I pass in some reporting string associated with every Option transformation:
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
}
Upvotes: 1
Views: 706
Reputation: 51271
I think what you want is an Either[String,String]
where the left projection is the failure message and the right projection is the result 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)
}
The .toRight()
method transforms an Option
into an Either
:
Some(x).toRight(y) //x.right
None.toRight(y) //y.left
Although, in truth, it's probably easier and clearer to use fold()
and getOrElse()
.
val reportFilteredCause :DomainObject => String = {
stringFetcher(_).fold("Failed to fetch string representation"){
filterer(_).getOrElse("Failed to filter field")
}
}
Upvotes: 3