En aquest tema, aprendrem com gestionar les excepcions en Haskell. La gestió d'excepcions és una part crucial de la programació, ja que ens permet manejar errors de manera controlada i evitar que el nostre programa falli de manera inesperada.

Conceptes Clau

  1. Excepcions en Haskell: Haskell proporciona mecanismes per capturar i manejar excepcions, especialment en el context de l'entrada i sortida (I/O).
  2. Tipus d'Excepcions: Hi ha diversos tipus d'excepcions que podem trobar, com ara errors de lectura/escriptura d'arxius, divisió per zero, etc.
  3. Maneig d'Excepcions: Utilitzarem funcions com catch, try, i handle per gestionar les excepcions.

Excepcions en Haskell

En Haskell, les excepcions es gestionen principalment en el context de les operacions d'I/O. Les excepcions es poden capturar i manejar utilitzant el mòdul Control.Exception.

Importació del Mòdul

import Control.Exception

Tipus d'Excepcions

Alguns dels tipus d'excepcions més comuns són:

  • IOException: Errors relacionats amb operacions d'I/O.
  • ArithException: Errors aritmètics, com la divisió per zero.
  • SomeException: Una excepció genèrica que pot capturar qualsevol tipus d'excepció.

Maneig d'Excepcions

Funció catch

La funció catch permet capturar una excepció i manejar-la amb una funció de maneig d'errors.

Sintaxi

catch :: IO a -> (SomeException -> IO a) -> IO a

Exemple

import Control.Exception

main :: IO ()
main = do
    result <- catch (readFile "nonexistent.txt") handler
    putStrLn result

handler :: SomeException -> IO String
handler ex = return $ "An error occurred: " ++ show ex

En aquest exemple, intentem llegir un arxiu inexistent. Si es produeix una excepció, la funció handler la captura i retorna un missatge d'error.

Funció try

La funció try retorna un valor de tipus Either, on Left conté l'excepció i Right conté el resultat de l'operació.

Sintaxi

try :: Exception e => IO a -> IO (Either e a)

Exemple

import Control.Exception

main :: IO ()
main = do
    result <- try (readFile "nonexistent.txt") :: IO (Either IOException String)
    case result of
        Left ex -> putStrLn $ "An error occurred: " ++ show ex
        Right content -> putStrLn content

En aquest exemple, utilitzem try per capturar l'excepció i manejar-la amb un case.

Funció handle

La funció handle és similar a catch, però amb els arguments invertits.

Sintaxi

handle :: (SomeException -> IO a) -> IO a -> IO a

Exemple

import Control.Exception

main :: IO ()
main = do
    result <- handle handler (readFile "nonexistent.txt")
    putStrLn result

handler :: SomeException -> IO String
handler ex = return $ "An error occurred: " ++ show ex

Exercicis Pràctics

Exercici 1: Maneig d'Excepcions en Lectura d'Arxius

Escriu un programa que intenti llegir un arxiu especificat per l'usuari. Si l'arxiu no existeix, captura l'excepció i mostra un missatge d'error.

Solució

import Control.Exception
import System.IO

main :: IO ()
main = do
    putStrLn "Enter the file name:"
    fileName <- getLine
    content <- catch (readFile fileName) handler
    putStrLn content

handler :: IOException -> IO String
handler ex = return $ "An error occurred: " ++ show ex

Exercici 2: Divisió Segura

Escriu una funció que realitzi una divisió segura, capturant l'excepció de divisió per zero i retornant un missatge d'error.

Solució

import Control.Exception

safeDivide :: Int -> Int -> IO (Either ArithException Int)
safeDivide x y = try (evaluate (x `div` y))

main :: IO ()
main = do
    result <- safeDivide 10 0
    case result of
        Left ex -> putStrLn $ "An error occurred: " ++ show ex
        Right value -> putStrLn $ "Result: " ++ show value

Resum

En aquesta secció, hem après com gestionar les excepcions en Haskell utilitzant les funcions catch, try, i handle. Hem vist exemples pràctics de com capturar i manejar excepcions en operacions d'I/O i en càlculs aritmètics. La gestió d'excepcions és una habilitat essencial per escriure programes robustos i fiables.

© Copyright 2024. Tots els drets reservats