Either is one of those types that you already know in Swift but it’s specialized in some values.
Here is it:
enum Either<Left, Right> {
case left(Left)
case right(Right)
}
Slo it’s an enum with two cases. That should ring at least two bells. Usually the right one is associated with the good or success or dextra. The left on the other hand is for bad, failure, error or you can say sinistra.
At least two types that are common in Swift are a specialization of this Either.
You can take a look at Optional and match left with none case. Also you can take a look at Result and match if failure with a left case.
So here you have a more generic type that you can use. It’s useful not only when you have to validate stuff. But also when there is a need to return different types.
Computed Properties
To make life a bit easier there are defined some helper properties.
Handy properties for logic checks.
var isLeft : Bool // true if `left` case
var isRight: Bool // true if `right` case
When you want to get to a value but you can deal with optional.
var right: Right?
var left : Left?
Take a look at OptionalAPI to see how working with Optional can be a pleasure.
It’s a function that takes a function expecting an instance of Right and produces a new instance of Either<Left, R>. Type R means NewRight but is abbreviated.
Either treats it’s right value a bit specially. This is analogous how Result and Optional treat some of their own cases.
That means that if you want to map an Either then by default you will be given an instance of a Right type.
So if you have:
func increment(_ i: Int) -> Int { i + 1 }
let right = Either<String,Int>.right(42)
right
.map(increment) // .right(43)
Final result is a new instance of Either<String,Int> with it’s right case holding 43. Same thing with left would do nothing.
let left = Either<String,Int>.left("I'm left")
left
.map(increment) // .left("I'm left")
This function takes two other functions as arguments. Left is the left transform and the right is the right transform. This results in a new instance of Either<L,R>.
This one is a map that combines leftMap and rightMap. More common name for it is biMap but I would like it be handy in the IDE and you can start typing just map and see what’s there.
This biMap can be used when you want to combine those transformations in to one statement:
right
.biMap({ $0.uppercased() }, increment) // .right(43)
left
.biMap({ $0.uppercased() }, increment) // .left("I'M LEFT")
This time a transform function returns another Either. This wold result in an Either Either like Either<Left, Either<Left, R>>. So using this flatMap (or another name you can fins bind) you can remove one layer of nesting.
Just as a side note, whenever you are using flatMap you are doing the dreaded monadic computation. You were calling flatMap on optionals and it was fine. And yes Optional is a Monad. If you want you can Google it just don’t overthink it and you will be just fine 😎
This might not be so common, but it’s a function that returns another function. The way it works you start with providing two functions. Left transform knows kow to produce T given an L. Right transform knows kow to produce T given an R.
Next step is the returned function. This one expects and Either<L,R> and when you provide an instance of this either then it will produce and instance of T.
lefts
func lefts<L,R>(_ eithers: [Either<L,R>] ) -> [L]
I guess type says it all. Give this function an array of either-s and in return you will get an array of Ls.
Either
Either is one of those types that you already know in Swift but it’s specialized in some values.
Here is it:
Slo it’s an enum with two cases. That should ring at least two bells. Usually the
right
one is associated with thegood
orsuccess
ordextra
. Theleft
on the other hand is forbad
,failure
,error
or you can saysinistra
.At least two types that are common in Swift are a specialization of this
Either
.You can take a look at Optional and match
left
with none case. Also you can take a look at Result and match if failure with aleft
case.So here you have a more generic type that you can use. It’s useful not only when you have to validate stuff. But also when there is a need to return different types.
Computed Properties
To make life a bit easier there are defined some helper properties.
Handy properties for logic checks.
When you want to get to a value but you can deal with optional.
Take a look at OptionalAPI to see how working with Optional can be a pleasure.
map
sIt’s a function that takes a function expecting an instance of
Right
and produces a new instance ofEither<Left, R>
. TypeR
meansNewRight
but is abbreviated.Either treats it’s right value a bit specially. This is analogous how Result and Optional treat some of their own cases.
That means that if you want to
map
anEither
then by default you will be given an instance of aRight
type.So if you have:
Final result is a new instance of
Either<String,Int>
with it’sright
case holding43
. Same thing with left would do nothing.rightMap
You can be explicit about it and call
rightMap
that is just a wrapper aroundmap
.leftMap
However if you want to transform a
left
value you can useleftMap
. Same story as for right but for left.biMap
This function takes two other functions as arguments. Left is the left transform and the right is the right transform. This results in a new instance of
Either<L,R>
.This one is a
map
that combinesleftMap
andrightMap
. More common name for it isbiMap
but I would like it be handy in the IDE and you can start typing just map and see what’s there.This
biMap
can be used when you want to combine those transformations in to one statement:flatMaps
Same as map above, but with one difference.
This time a transform function returns another Either. This wold result in an Either Either like
Either<Left, Either<Left, R>>
. So using this flatMap (or another name you can finsbind
) you can remove one layer of nesting.Just as a side note, whenever you are using
flatMap
you are doing the dreaded monadic computation. You were callingflatMap
on optionals and it was fine. And yes Optional is aMonad
. If you want you can Google it just don’t overthink it and you will be just fine 😎Utils
either
This might not be so common, but it’s a function that returns another function. The way it works you start with providing two functions. Left transform knows kow to produce
T
given anL
. Right transform knows kow to produceT
given anR
.Next step is the returned function. This one expects and
Either<L,R>
and when you provide an instance of this either then it will produce and instance ofT
.lefts
I guess type says it all. Give this function an array of either-s and in return you will get an array of
L
s.rights
I guess type says it all. Give this function an array of either-s and in return you will get an array of
R
s.partitionEithers
Returns a tuple containing all
L
values in theleft
/first array. And all theR
in theright
/ second array.YouTube
If you know 🇵🇱 then you can check out this YT playlist Either - Monada Either w Swift
🐇🕳 Rabbit Hole
This project is part of the 🐇🕳 Rabbit Hole Packages Collection