Na mônada de erro, a primeira falha interrompe ainda mais a execução, apenas levando a falha através das ligações seguintes.
Que mônada pára no sucesso apenas levando adiante sucessos e basicamente engolindo falhas e tentando o próximo vínculo, desconsiderando o fracasso do anterior?
Talvez a mônada de erro possa ser usada para tratar essa falha como um sucesso, mas estou curioso para saber se as bibliotecas padrão têm uma mônada para esse fim específico, quase como uma mônada Ou na minha mente "Faça isso ou aquilo"
Editar:
O comportamento seria:
Left "fail" >>= (\x -> Right "win") >>= (\x -> Left "ahh neener") >>= (\x -> Right (x + " yay"))
Na mônada de erro, o primeiro valor à esquerda é apenas transportado, portanto o resultado é Left "fail"
. O comportamento que eu quero é onde o retorno acima Right "win yay"
é uma mônada trivial para implementar, eu poderia escrever por mim mesmo, mas percebi que existia algo para fazer isso (talvez não esteja usando o Either, mas é a primeira coisa que vem à mente para esse comportamento).
Respostas:
O que você precisa é o MonadPlus (veja também o wiki do Haskell ). Define
que representa um erro não especificado e
que tenta o segundo cálculo, se o primeiro falhar. Algumas funções auxiliares também são fornecidas:
As instâncias de
MonadPlus
podem ser divididas em duas categorias:mplus
combina todos os resultados possíveis de ambos os seus argumentos (satisfaz a lei de distribuição à esquerda).[]
eSeq
provavelmente são as únicas instâncias com esse comportamento.mplus
seleciona o argumento esquerdo, se ele contiver um valor válido, caso contrário, ele seleciona o argumento correto (satisfaz a lei de captura de esquerda). Instâncias com este comportamento sãoMaybe
,Either
,STM
eIO
.(a
MonadPlus
instânciaEither
costumava ser definida em Control.Monad.Error comomas, por algum motivo, parece estar faltando na versão atual.)
Veja também MonadPlus no Wikilivros e definição de MonadPlus para Haskell IO .
fonte
Seq
também é uma instância doMonadPlus
. Eu recomendo fortemente[]
, porque concatenação (mplus
) paraSeq
é O (log n) enquanto concatenação de listas é O (n) .