2012-10-22 16 views
22

Widziałem wielokrotnie fragmenty kodu scala za pomocą Opcji (dla prostych wartości) lub [Lista [Błąd], T] do obsługi błędów.Czy stosowanie wyjątków to zła praktyka w scala?

daje to miejsce na kod jak poniżej

def createApplicationToken(accessToken: AccessToken): Either[List[Error], ApplicationToken] = { 

// go to social info provider and fetch information 
retrieveProviderInfo(accessToken).fold(
    errors => Left(errors), 
    info => { 
    // try to find user using the info from the provider 
    // if it's not there, create user 
    User.findOrCreateFromProviderInfo(info).fold(
     errors => Left(errors), 
     user => { 
     // try to create a fresh token and save it to the user 
     user.refreshApplicationToken.fold(
      errors => Left(errors), 
      user => Right(user.token) 
     ) 
     } 
    ) 
    } 
) 

który wytwarza kod nie tak piękny zagnieżdżania, zmusza do czynienia z awariami na każdym kroku, a także zmusza do mieć wszystkie funkcje zwracają Albo [ ...]

Więc chciałbym wiedzieć, czy

  • stosowanie wyjątków jest zalecane w Scala (lub programowania funkcyjnego w ogóle)

  • są jakieś niedogodności w korzystaniu z nich (dotyczące niezmienności lub kodu współbieżności)

  • wyjątki są w jakiś sposób w sprzeczności z zasadami lub programowania funkcyjnego

  • można myśleć o lepszym sposobem Kodeksu podany przykład

-

Można by uniknąć zagnieżdżania zamykając FUNCT jon natychmiast po wykryciu błędu za pomocą instrukcji return, ale użycie zwrotu również jest odradzane w scala ...

+3

pokrewne http://stackoverflow.com/questions/12886285/throwing-exceptions-in-scala-what-is-the-official-rule –

+0

dzięki za link ... – opensas

+3

Flatmap that shit –

Odpowiedz

21

Następująca wersja wykorzystuje fakt, że prawy rzut Either jest monadą i jest dokładnie taki sam jak twój Kod:

def createApplicationToken(accessToken: AccessToken) = for { 
    info <- retrieveProviderInfo(accessToken).right 
    user <- User.findOrCreateFromProviderInfo(info).right 
    refr <- user.refreshApplicationToken.right 
} yield refr.token 

i robi dużo lepszą pracę popisać zalety Either.

Bardziej ogólnie, reguły są takie same jak w Javie: używaj wyjątków w wyjątkowych sytuacjach. Może się okazać, że zmienisz swoją definicję wyjątkową trochę, gdy pracujesz w tym stylu - np. Nieprawidłowe dane wejściowe użytkownika nie są naprawdę wyjątkowe, przekroczenie limitu czasowego żądania sieciowego nie jest naprawdę wyjątkowe, itp.

+1

Co byłoby wyjątkowe? Zapytaj, bo podałeś przykłady rzeczy, które nie są, niektóre przykłady, które są wyjątkowe, byłyby miłe. – pedrofurla

+0

W moim przykładzie każdy krok może się nie udać, wciskając informacje ze strony twitter | facebook, tworząc użytkownika z informacji o Twitterze i tworząc nowy token i zapisując go użytkownikowi ... Czy uważasz je za wyjątkowe? Świetna odpowiedź, BTW – opensas

+0

@opensas: Nie twierdzę, że istnieje tu trudna linia, ale nie - modelowałbym wszystkie tego typu awarie z 'Albo' (lub' Validation 'Scalaz'). –

3

jak OM-nom-nom powiedział, zadałem podobne pytanie: Throwing exceptions in Scala, what is the "official rule"

Ale to nie jedyny poprosiłem, które mogą Cię zainteresować, bo używany do kodowania z wieloma standardowy kod i wiele poziomów wcięć ze względu na dopasowanie wzoru itp ...


+0

dzięki za linki, mam więcej pytań o SO na moim własne: http://stackoverflow.com/questions/12067296/scala-how-to -handle-validations-in-a-functional-way?rq=1, http://stackoverflow.com/questions/12547419/scala- idiomatyczne i funkcjonalne-sposób-dodać-błędy-do-listy-błędów? rq = 1 – opensas

+0

miło :) thx sprawdzi, czy –

2

odpowiedź zmienia się pomiędzy tym, co jest idealna, co jest praktyczne. Najlepiej, unikać Wyjątkiem jest to, że praktycznie nie możesz bez nich żyć

Scala wydaje się faworyzować jedno-liniowce i wzdłuż tych linii v2.10 ma nową mona d Spróbuj:

import scala.util.Try 

def percentCompleted(total:Int, done:Int): Int = Try (done * 100/total) getOrElse 100 

percentCompleted(0, 10) // Catches divide-by-zero and returns 100% instead 
+0

+1 dla "Praktycznie, nie możesz żyć bez nich . " – opensas

Powiązane problemy