Closed doomchild closed 5 years ago
Disagree. TryAsync<A>
is essentially Either<Task<Exception>, Task<A>>
. Just the left must always be an Exception
. The two sides are still mappable, but the resulting type of the left-hand-side must always be the same, even if the value has been mapped. So, it will stay as BiMap
.
How is that a BiMap
at all, though?
Maybe I'm leaning too hard on the Haskell idea of what these concepts mean, but bimap :: (a -> b) -> (c -> d) -> p a c -> p b d
(from https://hackage.haskell.org/package/bifunctors-5/docs/Data-Bifunctor.html) tells me that after a bimap
has occurred, the left and right sides do not have to be the same type. TryAsync.BiMap
is requiring both sides to turn into the same type. I would expect the signature to be BiMap<TResult>(Func<A, TResult> rightMorphism, Func<Exception, Exception> leftMorphisM)
.
I think of Fold
as being behavior specific to the case of having (potentially) multiple instances of a single thing (i.e. IEnumberable<>
or Seq<>
).
Instead, the first thought that comes to my mind would be to rename this TryAsync.BiMap
to TryAsync.Match
. That seems consistent to me with the Match
method for Either<L, R>
, which is
public Ret Match<Ret>(Func<R, Ret> Right, Func<L, Ret> Left, Func<Ret> Bottom = null)
Yeah, you could call it Match
, and that would make sense, because all of the other Match
methods coerce both sides of the disjunction into the same type.
The two functions passed to
TryAsync.BiMap
areA -> B
andException -> B
. This is a fold or a reduce, not a bimap. I ran into this when trying to write aTap
function forTryAsync
, which I would normally write like this:This is obviously not possible if both sides of
BiMap
must resolve to the same type.I'm aware that this is introducing a side effect, and that it's not necessarily good functional style. But sometimes you can't ignore a side effect (logging, for example, is entirely side-effecty), and a function like this is a whole lot easier to write and maintain on a team without a lot of functional grounding than a full
State
/Reader
/Writer
setup.I think
TryAsyncExtensions.BiMap
should either be renamed toFold
if the behavior is intended, or changed to allow a properbimap
to happen.