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

¿Cómo puedo ver el error resultante?¿Cómo funciona el manejo de excepciones Haskell?

+2

Ver también http://stackoverflow.com/questions/3642793/why-can-haskell-exceptions-only-be-caught-inside-the-io-monad –

+0

Realmente no importa, es solo una cuestión de tiempo antes de que la biblioteca de fallas seguras tome el control del mundo ;-). –

+0

¿Qué biblioteca de fallas seguras? – qrest

Respuesta

14

código Pure puede lanzar asíncrono, imprecise exceptions, por ejemplo, cuando una función parcial encuentros de entrada que tiene ningún caso de manejar.

Estos son errores lógicos, generalmente, que indican errores en la especificación del programa.

Pueden estar atrapados en el código IO (generalmente en una capa externa del programa), a través de exception handler.

Por ejemplo, para recuperar el caso que falta para la lista vacía,

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

Podemos observar que se detecta la excepción, y el programa termina.

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

Creo que el programa también es un error en su excepción andler :-) –

+4

Este programa no es un conducto. –

+0

Este intercambio me ha proporcionado mucha satisfacción. – sclv

4

purista respuesta: el resultado es indefinido (específicamente, bottom). No puede hacer nada con eso, excepto que falla si el valor se usa de alguna forma para generar los resultados del programa. Ver Haskell 98 Report section 3.1. Especifica que tales "errores causan la terminación inmediata del programa y no pueden ser capturados por el usuario".

Lo mejor es comprobar los valores de entrada y manejarlos ANTES de que puedan llegar tan lejos. No use fold1 si la lista puede tener 0 elementos.

Sin embargo, en la práctica, puede usar los métodos en las otras respuestas para capturarlo en IO cuando usa GHC. Las excepciones no pueden capturarse en código puro (no IO) porque elevar una excepción es un cambio en el flujo de control es un efecto secundario, no un cálculo puro.