I have a situation where I want to perform a series of operations (with side-effects) where I am only interested if they produced an error or not, and therefore their return type would be an Option[Error].
I want to chain several of those operations in a for comprehension, which leads to something like that:
You want to stop at the first error or would you like to collect all of them?
Assuming you only want the first error, how important would it be to avoid executing the others?
What libraries are you open to use? Like cats, cats-effect & fs2?
What parts of the code can be modified?
And ultimately what does “better” means for you in this case?
I don’t follow the “therefore”. A more appropriate type than Option[Error] seems to be Either[Error, Unit] (which is what you’re creating as an intermediate result in your transformation). What’s wrong with that?
But you are using it like this inside your transformation already.
Unit is the standard way of declaring that a function won’t produce an actionable result value but only exists for its side effects. “Lifting” this to Either's RHS means that there’ll be no actionable value for the result of a successful computation. This isn’t any more odd than plain Unit as a result type.
Cats et al. provide some sugar for ignoring the results in a successful computation chain so you can write something like
op1("x") >> op2("x")
(You can implement this on your own, of course, based on #flatMap().)
Of course you could implement your own ADT whose API directly encodes the desired behavior, without threading Unit through everywhere. But I’d think Either is just fine and won’t puzzle anybody.
…but op1 and op2 cannot be modified and encode their failure mode via Option? I’d think that’s unconventional to say the least, and I’d immediately convert to Either at the boundaries of my code base.