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

Comment puis-je détecter l'erreur qui en résulte?Comment fonctionne la gestion des exceptions Haskell?

+2

Voir aussi http://stackoverflow.com/questions/3642793/why-can-haskell-exceptions-only-be-caught-inside-the-io-monad –

+0

Peu importe, ce n'est qu'une question de temps avant que la bibliothèque de sécurité-échec prenne le monde ;-). –

+0

Quelle bibliothèque de sécurité-échec? – qrest

Répondre

14

pur code peut lancer asynchrone, imprecise exceptions, par exemple, lorsqu'une fonction partielle entrée rencontre, il n'a aucun cas manipuler.

Il s'agit généralement d'erreurs logiques indiquant des bogues dans la spécification du programme.

Ils peuvent être pris dans le code IO (généralement à une couche externe du programme), via un exception handler.

Par exemple, pour attraper votre cas manquant pour la liste vide,

{-# 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() 

Nous pouvons observer que l'exception est pris, et le programme se termine.

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

Je pense que le programme aussi comme un bug dans son exception andler :-) –

+4

Ce programme n'est pas un tuyau. –

+0

Cet échange m'a apporté beaucoup d'appétence. – sclv

4

puriste réponse: le résultat est indéfini (en particulier, bottom). Vous ne pouvez rien faire sauf crash si la valeur est utilisée de quelque façon que ce soit pour construire les résultats du programme. Voir Haskell 98 Report section 3.1. Il précise que de telles "erreurs provoquent la fin immédiate du programme et ne peuvent être interceptées par l'utilisateur".

Il est préférable de vérifier les valeurs d'entrée et de les gérer AVANT de pouvoir aller aussi loin. N'utilisez pas fold1 si la liste peut contenir 0 élément. En pratique cependant, vous pouvez utiliser les méthodes des autres réponses pour l'attraper dans IO lors de l'utilisation de GHC. Les exceptions ne peuvent pas être capturées dans le code pur (non-IO), car le fait de déclencher une exception est un changement dans le flux de contrôle est un effet secondaire, pas un calcul pur.