Closed SuheylZ closed 5 years ago
How about this?
return data.IfRight(x => $"{x.Item1}-{x.Item2}")
what about the left side? i need both
I'm sorry. I don't know what you mean. The code I wrote is equivalent to the two code examples that you gave.
Can you give another example of what you want?
actually consider this that left is as valid as right but only one at a time. so you have the same line of code but sometimes you have the value in right and sometimes in left. you want two functions to Map the value to the destination type which is the same for both left and right. so for instance
Either<(int id, EmailTypes type, string notes), (int id, PhoneTypes type)> data;
...
var rec = new DataRow;
data.Match(
x=> rec = new DataRow(x.id, (int)x.type),
y=> rec = new DataRow(y.id, (int)y.type, y.notes)
);
_repository.Save(rec);
as you can see we are changing rec but at the same time we are not ignoring left side. When the left side is valid, it is as much important as the right one and Match() does not return value as it takes an Action<> not Func<>
so what I'm looking for is this and this is possible only if Match() can also take Func<>
_repository.Save( data.Match(
x=> new DataRow(x.id, (int)x.type),
y=> new DataRow(y.id, (int)y.type, y.notes))
);
when you wrote this
return data.IfRight(x => $"{x.Item1}-{x.Item2}")
What happens if it is Left and not right? a None perhaps?
and this is possible only if
Match()
can also takeFunc<>
It does. All Match
methods for all types have Func
and Action
variants.
You can use Match
to map the types: you're using the Action
variants for some reason, but it isn't necessary - the Func
variants of Match
does what you need.
A more elegant way if you're going to be mapping to a common type if to use BiMap
, Map
, or MapLeft
to unify the left and right types.
You could also create an extension method for getting the common bound value:
public static A ToValue<A>(this Either<A, A> ma) =>
ma.Match(identity, identity);
So, on your first example:
Either<string, (int, string)> data;
var result = data.Map(x=> $"{x.Item1}-{x.Item2}").ToValue();
Which is the same as:
Either<string, (int, string)> data;
var result = data.Match(Right: x=> $"{x.Item1}-{x.Item2}", Left: identity);
Your second example:
Either<(int id, EmailTypes type, string notes), (int id, PhoneTypes type)> data;
var rec = data.BiMap(Right: x => new DataRow(x.id, (int)x.type),
Left: y => new DataRow(y.id, (int)y.type, y.notes))
.ToValue();
Which is the same as:
Either<(int id, EmailTypes type, string notes), (int id, PhoneTypes type)> data;
var rec = data.Match(Right: x => new DataRow(x.id, (int)x.type),
Left: y => new DataRow(y.id, (int)y.type, y.notes));
Stop using the imperative setting of values within the Action
delegates, use the Func
variants and return a value, it'll just get you into trouble eventually. The Action
variants are for launching side-effecting operations, not for mapping to values.
Consider this code:
Instead of the above, is there a way to achieve this:
return data.Match(x=>$"{x.Item1}-{x.Item2}", y=> y);