-- PROGRAMACION DECLARATIVA -- SOLUCIONES CONTROL 1 (P.FUNCIONAL) (13.4.2000) -- 1. Dado el programa Haskell: fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) lf :: Integer -> [Integer] lf 0 = [1] lf n = (fact n) : lf (n-1) -- (a) Indicar el tipo de f en la siguiente expresión. -- Justificar brevemente la respuesta. -- -- f (lf 5) (f (lf 3) 1) -- -- -- f :: [Integer] -> Integer -> Integer -- -- -------------- --------- ------------ -- tipo de (lf 5) tipo de 1 tipo del segundo -- argumento de f -- (b) Indicar a qué se reduce la siguiente expresión. -- Justificar brevemente la respuesta. -- -- let a:b:c = lf 3 in 0 : if b*b < a then c else [] -- -- ----> let a:b:c = [6,2,1,1] in 0 : if b*b < a then c else [] -- -- ----> 0 : if 2*2 < 6 then [1,1] else [] -- -- ----> [0,1,1] --(c) Implementar una función que mejore la eficiciencia de lf -- (obsérvese que calcula todos los factoriales sin tener en -- cuenta los ya calculados). lf2 :: Integer -> [Integer] lf2 0 = [1] -- Idea parecida a la obtencion de lf2 n = let (h:t) = lf2 (n-1) -- primos (visto en clase) in n*h : h : t {- otra forma, con parametros acumuladores: lf2 n = lf' n 0 [1] -- usamos dos parametros acumuladores: -- uno para saber por donde vamos, -- inicializado a 0, y otro con las -- soluciones parciales lf' :: Integer -> Integer -> [Integer] -> [Integer] lf' n m (x:t) = if n == m -- hemos alcanzado el valor de entrada n then x:t else lf' n (m+1) ((m+1)*x:x:t) -} -- 2 Implementar una función Haskell que trenza las listas dadas en -- una lista de listas. Por ejemplo, con [[1,2,3],[10,20], -- [100,2000,3000]] obtiene [1,10,100,2,20,2000,3,3000], con -- ["la","lista"] obtiene "llaista", etc. trenza :: [[a]] -> [a] trenza [] = [] trenza ([]:t) = trenza t trenza ((x:r):t) = x : trenza (t ++ [r]) -- 4. Dado el tipo data Vehiculo a = Coche a | Moto a -- implementar una función que distribuye una lista de vehículos -- en dos grupos: uno con los coches y otro con las motos. dist :: [Vehiculo a] -> ([Vehiculo a],[Vehiculo a]) dist [] = ([],[]) dist (h:t) = let (l1,l2) = dist t in case h of Moto _ -> (l1, h:l2) Coche _ -> (h:l1, l2) {- o bien, sin case: dist [] = ([],[]) dist ((Moto x):t) = let (l1,l2) = dist t in (l1, (Moto x):l2) dist ((Coche x):t) = let (l1,l2) = dist t in ((Coche x):l1, l2) -}