2010-09-05 18 views
10
foldl1 (+) [] 

Jak złapać wynikowy błąd?Jak działa obsługa wyjątków Haskell?

+2

Zobacz także http://stackoverflow.com/questions/3642793/why-can-haskell-exceptions-only-be-caught-inside-the-io-monad –

+0

To naprawdę nie ma znaczenia, to tylko kwestia czasu, zanim biblioteka "safe-failure" przejęła świat ;-). –

+0

Jakiej bezpiecznej biblioteki? – qrest

Odpowiedz

14

Czysty kod może rzucić asynchroniczny, imprecise exceptions, na przykład, gdy częściowy funkcja napotka wejście to nie ma sprawy w obsłudze.

Są to błędy logiczne, zwykle wskazujące na błędy w specyfikacji programu.

Mogą zostać przechwycone w kodzie IO (zwykle w zewnętrznej warstwie programu), za pośrednictwem exception handler.

Na przykład, aby złapać brakujące sprawę do pustej listy,

{-# LANGUAGE ScopedTypeVariables #-} 
{-# LANGUAGE BangPatterns  #-} 

import Control.Exception 

main = do 
    handle (\(e :: SomeException) -> print $ "This program as a bug: " ++ show e) $ do 
     let !v = foldl1 (+) ([] :: [Int]) 
     return() 

Możemy zaobserwować, że wyjątek zostanie złapany, a program kończy.

$ ./A 
"This program as a bug: Prelude.foldl1: empty list" 
+4

Myślę, że program również jako błąd w jego wyjątku andler :-) –

+4

Ten program nie jest fajką. –

+0

Ta wymiana przyniosła mi wiele apelacji. – sclv

4

Purist odpowiedź: wynik jest niezdefiniowany (konkretnie bottom). Nie możesz nic z tym zrobić, oprócz awarii, jeśli wartość jest używana w jakikolwiek sposób do budowania wyników programu. Zobacz Haskell 98 Report section 3.1. Określa, że ​​takie "błędy powodują natychmiastowe zakończenie programu i nie mogą zostać przechwycone przez użytkownika".

Najlepiej sprawdzić wartości wejściowe i obsłużyć je, ZANIM osiągną tak daleko. Nie używaj fold1, jeśli lista może zawierać 0 elementów.

W praktyce jednak można użyć metod z innych odpowiedzi, aby złapać go w IO podczas korzystania z GHC. Wyjątki nie mogą zostać przechwycone w czystym kodzie (innym niż IO), ponieważ podniesienie wyjątku jest zmianą w przepływie sterowania, jest efektem ubocznym, a nie czystym obliczeniem.