Qualcosa che mi succede molto durante la programmazione web: voglio eseguire un'operazione che ha una possibilità di fallimento. In caso di fallimento, voglio inviare al client un 500. Normalmente, però, voglio solo continuare a eseguire una serie di passaggi.Come "scappare presto" in una web monad
doSomeWebStuff :: SomeWebMonad()
doSomeWebStuff = do
res <- databaseCall
case res of
Left err -> status 500
Right val -> do
res2 <- anotherDatabaseCall (someprop val)
case res2 of
Left err -> status 500
Right val2 -> text $ show val2
poiché gli errori sono eccezioni, non mi piace il fatto che ho bisogno di tutto quel materiale per catturarli. Voglio fare la stessa cosa ogni volta che è una sinistra. C'è un modo per esprimerlo su una riga con qualcosa come guard
, ma controllare cosa restituisce in uscita?
in un'altra lingua ho potuto fare questo:
function doSomeWebStuff() {
var res = databaseCall()
if (res == Error) return status 500
var res2 = anotherDatabaseCall(res.someprop)
if (res2 == Error) return status 500
return text(res2)
}
Quindi, sto bene a scrivere un po 'di testo standard, ma non voglio gli errori a pasticciare con la mia nidificazione, quando è molto più comune di appena voglio continuare con il caso trovato.
Qual è il modo più pulito per farlo? So che in teoria posso usare una monade per uscire presto in caso di errore, ma ho visto solo esempi con Maybe
e restituirei Nothing
alla fine, piuttosto che permettermi di specificare cosa restituisce.
Un bellissimo esempio del perché le leggi Monade sono utili :) –
La monade 'Either' può essere utilizzato per l'uscita anticipata con un valore di ritorno (' Left'). – shang
@shang Al giorno d'oggi, 'o''s' fail' è' error', è probabile che fornisca alcuni effetti indesiderati.Consiglio di guardare "ErrorT'. –