In Haskell, posso usare il tipo a -> Maybe b
per modellare una funzione che restituisce un valore di tipo b
, o restituisce nulla (non riesce).
Se ho tipi a1, ..., a(n+1)
e funzioni f1, ..., fn
, con fi :: ai -> Maybe a(i+1)
per tutto i
, 1 <= i <= n
, posso concatenare le funzioni utilizzando l'operatore >>=
di Maybe
monad e scrivi :
f1 x >>= f2 >>= f3 >>=... >>= fn
L'operatore >>=
garantisce che ciascuna funzione venga applicata finché il suo predecessore ha restituito un valore significativo. Non appena una funzione nella catena fallisce, l'intera catena fallisce (restituisce Nothing
) e non vengono valutate ulteriori funzioni nella catena.
Ho uno schema un po 'simile nel quale voglio provare diverse funzioni sullo stesso input, e tornare non appena una funzione riesce . Se tutte le funzioni falliscono (return Nothing
), l'intera computazione dovrebbe fallire. Più precisamente, ho funzioni f1, ..., fn :: a -> Maybe b
e definisco la funzione
tryFunctions :: [a -> Maybe b] -> a -> Maybe b
tryFunctions [] _ = Nothing
tryFunctions (f : fs) x = case f x of
Nothing -> tryFunctions fs x
r@(Just _) -> r
In un certo senso questo è duale al Maybe
monad in quanto un calcolo si arresta al primo successo invece che al primo errore.
Ovviamente, posso usare la funzione che ho scritto sopra, ma mi chiedevo se c'è un modo migliore, consolidato e idiomatico di esprimere questo modello in Haskell.