Coś, co mi się przydarza podczas programowania stron internetowych: Chcę uruchomić operację, która ma szansę na niepowodzenie. W przypadku niepowodzenia chcę wysłać klientowi 500. Zazwyczaj jednak chcę kontynuować wykonywanie serii kroków.Jak "uciec wcześnie" w monadzie internetowej
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
ponieważ błędy są wyjątkami, nie podoba mi się, że potrzebuję tych wszystkich rzeczy, żeby je złapać. Chcę zrobić to samo, ilekroć coś jest lewe. Czy istnieje sposób, aby wyrazić to w jednym wierszu z czymś takim jak guard
, ale kontrolować, co zwraca na wyjściu?
w innym języku mogę to zrobić:
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)
}
Tak, jestem ok pisząc jakiś boilerplate, ale nie chcę błędów zadzierać z moim gniazdowania, gdy jest znacznie bardziej powszechne, aby po prostu chcesz kontynuować dalej w znalezionym przypadku.
Jaki jest najczystszy sposób to zrobić? Wiem, że teoretycznie mogę użyć monady, aby wcześnie zakończyć awarię, ale widziałem tylko przykłady z Maybe
i na końcu powrócą na koniec Nothing
, zamiast pozwalać mi określić, co powróci.
Piękny przykład dlaczego przepisy Monad są przydatne :) –
Opcja 'Either' monada może być stosowany do wczesnego wyjścia z wartości zwracanej (' Left'). – shang
@shang Obecnie 'Albo' '' '' 'jest' błędem', które prawdopodobnie dają kilka niepożądanych efektów.Polecam patrząc na 'ErrorT'. –