Filter/Map Either's Right to a Left
See original GitHub issueSay I have the following method:
public async Task<Either<Exception,int>> GetCurrentJobNumber()
{
// Build the job URI, which will then return the JSON.
return (await _server.FetchJSON<JenkinsJob>(GetJobURIStem()))
.Map(v => v.lastCompletedBuild)
.Map(v => v.number);
}
The FetchJSON will return an Either<Exception, JenkinsJob>. I’d like to then filter on lastCompletedBuild being null. However, if it is null, then I want to convert the Either to be a Right (new Exception(“No job has been run”)).
Is there a way to accomplish this?
Many thanks for the library! I’m just starting to try to use it. it is quite viral, but it turns functions like above from 10 lines of code into 3 very clear ones.
Issue Analytics
- State:
- Created 7 years ago
- Comments:11 (5 by maintainers)
Top Results From Across the Web
Spark filter + map vs flatMap - scala
isLeft).map(case Left(a) => a) val rddB = rddEither.filter(_.isRight).map(case Right(b) => b). flatMap val rddA = rddEither.
Read more >filterMap - javadoc.io
filterMap. common. fun <K, A, B> Map<K, A>.filterMap(f: (A) -> B?): Map<K, B>. Content copied to clipboard. © 2022 CopyrightGenerated by dokka.
Read more >Introduction to Vavr's Either
An Either is either a Left or a Right. By convention, the Left signifies a failure case result and the Right signifies a...
Read more >FilterMap in rayon::iter - Rust
FilterMap ` creates an iterator that uses `filter_op` to both filter and map ... Either::Left items go into the first container, and Either::Right...
Read more >FilterMap in rayon::iter - Rust
FilterMap ` creates an iterator that uses `filter_op` to both filter and map ... Either::Left items go into the first container, and Either::Right...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@gordonwatts It’s a slightly awkward one, but a general rule-of-thumb if you want to change the monad itself rather than the value stored within it, then use
Bind
:So where
Map
has the signatureFunc<T, R>
;Bind
has the signatureFunc<T, M<R>>
whereM
is the monad.With your example you’re switching from
Right
toLeft
and therefore working on the monad, rather than just mapping the values within.This is an example with
Bind
It’s still not super pretty because
Either
requires two generic type params and therefore the type-inference is non-existent. What I’ll often do when usingEither
is to create somestatic
helper functions for creating theRight
andLeft
states for the common<L,R>
pairs.For example with a couple of functions (and
using static ...
):The code becomes much more declarative:
With cunning use of extension methods targeted at specific types (in this case
JenkinsJob
):Then you have a reusable function that is super clear:
You could go even further and use the
NewType
system to give meaning to yourint
(and make it type-safe):And update the helper functions to use it:
Then your resulting function looks like this:
The final result is a function that declares its intentions entirely.
Hope that helps! 😃
Actually, I don’t see
Option<>.Value
inlanguage-ext
. I was either getting confused between F#'sOption<>.Value
or a custom extension method like the following that someone could write forOption<>
inlanguage-ext
.Either way, I have still seen people write (bad) code like that even if it wasn’t exactly C# and vanilla
language-ext
.Here is how you get the valid ones.
In C# (and my other programming languages), the syntax for function application uses a prefix notation.
The purpose of
Apply
is to change function application (if you “squint”) to a postfix notation.I wrote about this in this post on my old blog. (I need to port that new my new blog.)