Introducció

Les monads són un concepte fonamental en Haskell i en la programació funcional en general. Encara que poden semblar complicades al principi, les monads proporcionen una manera poderosa i flexible de gestionar efectes com l'entrada/sortida, l'estat, les excepcions, i més, dins d'un context purament funcional.

Què és una Monad?

Una monad és una estructura que representa càlculs seqüencials. En Haskell, una monad és una classe de tipus amb tres components principals:

  1. Tipus de Dades: Un tipus de dades que encapsula un valor.
  2. Operació return: Una funció que pren un valor i el posa dins d'una monad.
  3. Operació >>= (bind): Una funció que pren una monad i una funció que retorna una monad, i les combina.

Definició de la Classe Monad

class Monad m where
    return :: a -> m a
    (>>=)  :: m a -> (a -> m b) -> m b
  • return pren un valor i el posa dins d'una monad.
  • >>= (bind) pren una monad i una funció, i aplica la funció al valor dins de la monad, retornant una nova monad.

Exemples de Monads

Maybe Monad

La monad Maybe s'utilitza per representar càlculs que poden fallar.

instance Monad Maybe where
    return = Just
    Nothing >>= _ = Nothing
    Just x  >>= f = f x

Exemple Pràctic

safeDivide :: Double -> Double -> Maybe Double
safeDivide _ 0 = Nothing
safeDivide x y = Just (x / y)

example :: Maybe Double
example = do
    a <- safeDivide 10 2
    b <- safeDivide a 2
    return b

IO Monad

La monad IO s'utilitza per representar càlculs que impliquen efectes d'entrada/sortida.

main :: IO ()
main = do
    putStrLn "Quin és el teu nom?"
    name <- getLine
    putStrLn ("Hola, " ++ name ++ "!")

Exercicis Pràctics

Exercici 1: Utilitzar la Monad Maybe

Escriu una funció que prengui dues llistes de nombres enters i retorni la suma dels seus elements corresponents, però només si les dues llistes tenen la mateixa longitud. Si no, retorna Nothing.

sumLists :: [Int] -> [Int] -> Maybe [Int]
sumLists xs ys
    | length xs /= length ys = Nothing
    | otherwise = Just (zipWith (+) xs ys)

Solució

sumLists :: [Int] -> [Int] -> Maybe [Int]
sumLists xs ys
    | length xs /= length ys = Nothing
    | otherwise = Just (zipWith (+) xs ys)

-- Exemple d'ús
exampleSum :: Maybe [Int]
exampleSum = sumLists [1, 2, 3] [4, 5, 6]  -- Just [5, 7, 9]

Exercici 2: Utilitzar la Monad IO

Escriu un programa que llegeixi dos nombres enters de l'entrada estàndard, els sumi i imprimeixi el resultat.

main :: IO ()
main = do
    putStrLn "Introdueix el primer nombre:"
    input1 <- getLine
    putStrLn "Introdueix el segon nombre:"
    input2 <- getLine
    let num1 = read input1 :: Int
    let num2 = read input2 :: Int
    putStrLn ("La suma és: " ++ show (num1 + num2))

Errors Comuns i Consells

  • Oblidar el return: Quan treballes amb monads, és fàcil oblidar utilitzar return per encapsular un valor dins d'una monad.
  • Confusió amb >>= i do: Recorda que do és només una sintaxi sucre per a una seqüència de càlculs monàdics. Pots utilitzar >>= directament si ho prefereixes.

Conclusió

Les monads són una eina poderosa en Haskell que permeten gestionar efectes de manera pura i funcional. Encara que poden semblar intimidants al principi, amb la pràctica esdevenen una part natural del teu arsenal de programació. En el proper tema, explorarem els funtors aplicatius, que són una generalització de les monads.

© Copyright 2024. Tots els drets reservats