Either<TLeft, TRight>
Last updated
Last updated
Esta classe representa valores "ou um ou outro".
Instâncias de Either<TLeft, TRight>
encapsulam um valor que pode pertencer a um dos dois possíveis tipos: TLeft
ou TRight
. Este valor só pode ser acessado através dos métodos Match
e Match2
.
Uma utilização comum deste tipo é uma alternativa ao tipo Option<T>
para lidar com possíveis erros, mas neste caso o estado "Não contendo nada" é substituído por um valor de um tipo diferente.
Por convenção o tipo TLeft
representa o tipo problemático enquanto o TRight
representa o tipo resultante no caminho feliz.
Os valores either possuem dois estados:
Esquerda (IsLeft
) - Quando contém um valor do tipo TLeft
;
Direita (IsRight
) - Quando contém um valor do tipo TRight
.
Você pode criar um valor either de várias formas diferentes, inclusive para atribuir mais informações à um valor Option<T>
.
Você pode utilizar o construtor para criar valores contendo o estado IsLeft
ou IsRight
de acordo com o parâmetro, conforme código:
Utilizando o construtor
Devido às sobrecargas de cast implícito você não precisa se preocupar com nenhum tipo de sintaxe e nem utilizar o construtor, basta criar o valor de um dos dois tipos TLeft
ou TRight
declarado e a linguagem fará todo o trabalho.
Utilizando cast implícito
Através deste cast implícito, você poderá gerar novos métodos para retornar o tipo Either em sua aplicação sem alterar nada no corpo especial da função, apenas indicando que a função retorna um valor Either e informando duas instruções de return com tipos diferentes.
Veja este exemplo:
Pode parecer estranho ter duas instruções de retorno com valores de tipos diferentes, mas na verdade ambos retornam um valor do tipo Either
, mas estamos deixando esta responsabilidade com o C#.
Assim como nos valores opcionais é necessário utilizar os métodos Match
ou Match2
para obter a informação de um valor Either, no entanto, existe a possibilidade de extrair a informação de um valor Either realizando um cast implícito para um valor opcional.
Neste caso o valor opcional terá que identificar um dos dois tipos TLeft
ou TRight
. Caso o tipo identificado pelo Option
seja o tipo referente ao estado atual do valor Either
será gerado um valor opcional no estado IsSome
, caso contrário será gerado no estado IsNone
.
Com isso, é necessário tratar adequadamente todas as possibilidades para obter um valor de um Either
.
Utilizando o cast implícito para Option
Atenção
Mesmo realizando o cast implícito para o tipo correto, podem haver casos onde o valor opcional esteja no estado IsNone.
Esta situação ocorre quando o valor armazenado no tipo Either é igual ao valor
default
ou igual ànull
.
Os métodos Match
esperam dois métodos por parâmetro, estes métodos podem realizar transformações no valor Either, ou apenas retorná-los, conforme exemplos:
Utilizando Match com parâmetros nomeados
O primeiro método será executado apenas se o valor either estiver no estado IsRight
, logo, este método recebe um valor do tipo à direita por parâmetro, int
, no exemplo.
O segundo método recebe um valor do tipo à esquerda, bool
, mas note que ambos precisam retornar valores do mesmo tipo. Portanto, foi utilizado o valor zero (0) para seguir o fluxo da aplicação caso o Either esteja no estado IsLeft
.
Não há necessidade de nomear os métodos, basta utilizá-los na ordem correta.
Utilizando Match
Além disso, você também pode aplicar algum tipo de transformação no valor no momento de obtê-lo, como por exemplo, elevá-lo ao quadrado.
Você também pode retornar o valor que precisar para o caso do estado ser IsLeft
, nos exemplos anteriores foi utilizado o valor zero, mas não há nenhuma obrigatoriedade nisso.
O método Match também não precisa retornar nenhum dos dois tipos do valor Either.
Utilizando Match para retornar um novo valor
Nos casos onde é necessário realizar uma comparação com dois valores Either de cada vez é necessário utilizar o método Match2
, este método é consideravelmente mais complexo, pois você terá de lidar com todas as possíveis combinações de resultado.
Utilizando Match2 com dois Either no estado IsRight
Neste exemplo está sendo realizada a soma de dois valores Either diferentes, no caso, ambos com o estado IsRight
, fazendo com que o primeiro método seja executado:
(value1, value2) => value1 + value2
Neste método anônimo o parâmetro value1
contém o valor armazenado pela variável either
(10) e o parâmetro value2
da variável either2
(15).
Neste exemplo a variável result
receberá o valor 25.
Para este tipo de comparação existem outros três resultados possíveis dependendo do estado de cada um dos valores Either:
Utilizando Match2 com os estados IsRight e IsLeft, respectivamente
Utilizando Match2 com os estados IsLeft e IsRight, respectivamente
Utilizando Match2 com dois Either no estado IsLeft
Tanto para o método Match
quanto para o método Match2
há uma sobrecarga onde os métodos informados não precisam retornar nenhum tipo de valor (void
).
O conceito dos valores "Ou um ou outro" pode ser encontrado na seção Conceitos > Valores "Ou um ou outro".
Nome
Tipo
Descrição
IsLeft
bool
Retorna true quando o valor contido no tipo either é do tipo definido por TLeft.
IsRight
bool
Retorna true quando o valor contido no tipo either é do tipo definido por TRight.
Parâmetros
Retorno
Descrição
TLeft left
Either<TLeft, TRight>
Inicializa uma nova instância de um valor Either com o estado IsLeft encapsulando o valor informado no parâmetro.
TRight right
Either<TLeft, TRight>
Inicializa uma nova instância de um valor Either com o estado IsRight encapsulando o valor informado no parâmetro.
Nome
Parâmetros
Retorno
Descrição
Match
Func<TRight,TResult> methodWhenRight
Func<TLeft, TResult> methodWhenLeft
TResult
Permite uma maneira de aplicar um método à um valor either sem necessidade de checar o estado do valor.
Para isso são passados dois métodos por parâmetro. Estes métodos precisam retornar o mesmo tipo e cada um deles deve esperar um parâmetro diferente, dos tipos TLeft e TRight. Eles serão chamados de acordo com o estado do valor Either (IsLeft ou IsRight).
Match2
Either<TLeft2, TRight2> either2
Func<TRight, TRight2, T> methodWhenBothRight
Func<TRight, TLeft2, T> methodWhenRightLeft
Func<TLeft, TRight2, T> methodWhenLeftRight
Func<TLeft, TLeft2, T> methodWhenBothLeft
T
Permite uma maneira de aplicar um método à dois valores either sem necessidade de checar os estados de cada valor.
Para isso são passados quatro métodos contendo o mesmo tipo de retorno por parâmetro, onde cada um deles será chamado de acordo com o estado dos dois valores either.
Match
Action<TRight> methodWhenRight
Action<TLeft> methodWhenLeft
Unit
Permite uma maneira de aplicar um método à um valor either sem necessidade de checar o estado do valor.
Para isso são passados dois métodos por parâmetro. Estes métodos precisam não conter retorno (void) e cada um deles deve esperar um parâmetro diferente, dos tipos TLeft e TRight. Eles serão chamados de acordo com o estado do valor Either (IsLeft ou IsRight).
Match2
Either<TLeft2, TRight2> either2
Action<TRight, TRight2> methodWhenBothRight
Action<TRight, TLeft2> methodWhenRightLeft
Action<TLeft, TRight2> methodWhenLeftRight
Action<TLeft, TLeft2> methodWhenBothLeft
T
Permite uma maneira de aplicar um método à dois valores either sem necessidade de checar os estados de cada valor.
Para isso são passados quatro métodos por parâmetro, onde eles precisam não retornar nenhum valor (void) e cada um será chamado de acordo com o estado dos dois valores either.
Operador
Parâmetros
Retorno
Descrição
Cast implícito
TLeft left
Either<TLeft, TRight>
Permite a criação de um valor Either através de um cast implícito de qualquer valor TLeft para seu respectivo valor Either.
Cast implícito
TRight right
Either<TLeft, TRight>
Permite a criação de um valor Either através de um cast implícito de qualquer valor TRight para seu respectivo valor Either.
Cast implícito
Either<TLeft, TRight>
Option<TLeft>
Permite a criação de um valor Option<TLeft> através de um cast implícito de um valor Either.
Caso o valor Either esteja no estado IsRight será criado um valor opcional no estado IsNone.
Cast implícito
Either<TLeft, TRight>
Option<TRight>
Permite a criação de um valor Option<TRight> através de um cast implícito de um valor Either.
Caso o valor Either esteja no estado IsLeft será criado um valor opcional no estado IsNone.
Cast implícito
Continuation<TLeft, TRight>
Either<TLeft, TRight>
Permite a criação de um valor Either<TLeft, TRight> através de um cast implícito de um valor Continuation.
Caso o valor Continuation esteja no estado IsFail será criado um valor Either no estado IsLeft, caso contrário, no estado IsRight.