2012-05-04 16 views
5

Chcę napisać funkcję saveStuff, która zapisuje coś do pliku, po przejściu niektórych testów. Jeśli testy zakończą się niepowodzeniem, muszę zgłosić błąd. Jaki powinien być typ wyniku tej funkcji? Pomyślałem o IO (Either String()) i IO (Maybe String), ale obaj z nich czują źle z jakiegoś powodu. Wyszukałem podobne funkcje z biblioteki standardowej, ale po prostu wydają się zwracać IO(). Wyrzucają wyjątki w razie awarii. Nie mogę znaleźć takiego podejścia.Jaki powinien być typ wyniku tej funkcji?

+7

Jeśli może się powieść tylko w jeden sposób, "Maybe ErrorMessage" lub coś takiego jest typem izomorficznym. Jeśli nie lubisz 'Maybe', ponieważ zwykle' Nic' wskazuje na niepowodzenie, użyj 'data Result = Success | Failure String'. –

+2

@ Daniel Fischer: To jest prawdopodobnie dobre jako odpowiedź (a nie komentarz). –

Odpowiedz

7

Można rozważyć coś pisze, że zwraca ErrorT String IO(). Dokumentacja dla transformatora monad ErrorT to on Hackage. W znakomitym numerze Eight Ways to Report Errors znalazło się więcej sugestii Erica Kidda i follow up kilka lat później Edwarda Yanga.

+0

"ErrorT" jest tym, o czym myślałem. Masz to, co zasadniczo jest 'IO()', i chcesz dodać potencjał do błędu z komunikatem, więc po prostu uderz w niego transformator 'ErrorT'. –

6

Jeśli istnieje tylko jeden sposób, aby saveStuff mógł się powieść, typ izomorficzny na Maybe ErrorMessage jest poprawny. Maybe ErrorMessage sam ma wadę, która zwykle oznacza, że ​​Nothing oznacza błąd podczas używania Maybe, więc byłoby to sprzeczne z oczekiwaniami tutaj. W związku z tym, Either ErrorMessage() jest lepszy, ale parametr () do przypadku Right nie zawiera żadnych informacji, dlatego ta opcja również nie ma elegancji.

Jeśli nie chcą przyjąć tych niedociągnięć, określić własny typ wynik

data Result = Success | Failure ErrorMessage 
-- with type ErrorMessage = String, for example 
Powiązane problemy