Qual mônada é o oposto do erro mônada em haskell

9

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).

Jimmy Hoffa
fonte
Por que o voto negativo? Existe algo de ruim nessa questão?
Jimmy Hoffa
Você poderia fornecer um pequeno trecho de código para mostrar o que pensa?
Daniel Gratzer
Será que você está pensando em voltar atrás?
scarfridge

Respostas:

4

O que você precisa é o MonadPlus (veja também o wiki do Haskell ). Define

mzero :: m a

que representa um erro não especificado e

mplus :: m a -> m a -> m a

que tenta o segundo cálculo, se o primeiro falhar. Algumas funções auxiliares também são fornecidas:

-- Extends `mplus` to lists of computations:
msum :: MonadPlus m => [m a] -> m a
-- Fails a computation conditionally.
guard :: MonadPlus m => Bool -> m ()
-- Filter (fail) computations that don't satisfy the predicate.
mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a

As instâncias de MonadPluspodem ser divididas em duas categorias:

  1. mpluscombina todos os resultados possíveis de ambos os seus argumentos (satisfaz a lei de distribuição à esquerda). []e Seqprovavelmente são as únicas instâncias com esse comportamento.
  2. mplusseleciona 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ão Maybe, Either, STMe IO.

(a MonadPlusinstância Eithercostumava ser definida em Control.Monad.Error como

instance (Error e) => MonadPlus (Either e) where
    mzero            = Left noMsg
    Left _ `mplus` n = n
    m      `mplus` _ = m

mas, por algum motivo, parece estar faltando na versão atual.)

Veja também MonadPlus no Wikilivros e definição de MonadPlus para Haskell IO .

Petr Pudlák
fonte
Obrigado, parece que a lista monadplus é o pensamento que eu tinha.
Jimmy Hoffa
@ JimmyHoffa Esqueci de mencionar que Seqtambém é uma instância do MonadPlus. Eu recomendo fortemente [], porque concatenação ( mplus) para Seqé O (log n) enquanto concatenação de listas é O (n) .
Petr Pudlák
O wiki do haskell é muito esclarecedor, parece que a comunidade do haskell está pensando em qual direção deve seguir da mesma maneira que eu estou pensando em qual direção quero que ela funcione; se eu quero que seja um Ou como um "Isto ou aquilo" ou um então, "Isto então aquilo" onde a primeira falha causa um comportamento como Ou usando o valor de pré-falha para a próxima, mas um sucesso ainda chama o o próximo, ao contrário de Or, e usa o valor retornado da primeira função.
Jimmy Hoffa
Sim, apoio a proposta de reforma do MonadPlus , acredito que isso esclareceria bastante as coisas.
Petr Pudlák 22/01