No Haskell, posso usar o tipo a -> Maybe bpara modelar uma função que retorna um valor do tipo bou não retorna nada (falha).
Se eu tiver tipos a1, ..., a(n+1)e funções f1, ..., fn, com fi :: ai -> Maybe a(i+1)para todos i, 1 <= i <= nposso encadear as funções usando o >>=operador da Maybemônada e escrever:
f1 x >>= f2 >>= f3 >>=... >>= fn
O >>=operador garante que cada função seja aplicada desde que seu predecessor retorne um valor significativo. Assim que uma função na cadeia falha, a cadeia inteira falha (retorna Nothing) e outras funções na cadeia não são avaliadas.
Eu tenho um padrão um pouco semelhante no qual desejo tentar várias funções na mesma entrada e retornar assim que uma função for bem-sucedida . Se todas as funções falharem (retornar Nothing), todo o cálculo falhará. Mais precisamente, tenho funções f1, ..., fn :: a -> Maybe be defino a função
tryFunctions :: [a -> Maybe b] -> a -> Maybe b
tryFunctions [] _ = Nothing
tryFunctions (f : fs) x = case f x of
Nothing -> tryFunctions fs x
r@(Just _) -> r
Em certo sentido, isso é duplo para a Maybemônada, pois um cálculo para no primeiro sucesso, e não na primeira falha.
Obviamente, posso usar a função que escrevi acima, mas fiquei pensando se há uma maneira melhor, bem estabelecida e idiomática de expressar esse padrão em Haskell.
Alternativeque é o operador símbolo infix <|>e é definido em termos de uma Monoid
return f1 ?? f2 ?? f3 ?? DefaultValue;