-- 1.- data Operador = Mas | Menos | Prod | Div deriving Eq -- para que puedan ser comparados en evaluar data ExpArit = Ent Int | Aplicar Operador ExpArit ExpArit -- se supone que contamos con la función evaluar:: ExpArit -> Int evaluar (Ent x) = x evaluar (Aplicar op exp1 exp2) | op == Mas = evaluar exp1 + evaluar exp2 | op == Menos = evaluar exp1 - evaluar exp2 | op == Prod = evaluar exp1 * evaluar exp2 | op == Div = evaluar exp1 `div` evaluar exp2 instance Ord ExpArit where e1 < e2 = evaluar e1 < evaluar e2 -- Como Ord es subclase de Eq, hay que añadir lo siguiente: instance Eq ExpArit where e1 == e2 = evaluar e1 == evaluar e2 -- 2.- f1 = (foldl1 min) . (foldl1 min) f2 = (foldl1 min) . (map (foldl1 min)) -- a) f1 :: Ord a => [[a]] -> a f2 :: Ord a => [[a]] -> a -- b) No producen los mismos resultados, por ejemplo: -- f1 [[3,8],[4,2,1]] se evalúa 3, porque foldl1 min [[3,8],[4,2,1]] vale [3,8] -- f2 [[3,8],[4,2,1]] se evalúa a 1, porque map (foldl1 min) [[3,8],[4,2,1]] vale [3,1] -- c) -- (f1 xxs) calcula el mínimo elemento de la menor lista, en orden lexicográfico, de xxs. -- (f2 xxs) calcula el mínimo elemento de todas las listas que hay en xxs. -- d) f3 :: Ord a => [[a]] -> a f3 = (foldl1 min) . concat -- es equivalente a f2 -- 3.- concatmap f = concat . (map f) -- a) concatmap :: (a -> [b]) -> [a] -> [b] -- b) g1 = concatmap (:[]) -- g1:: [a] -> [a] -- g1 es equivalente a la función identidad -- c) g2 = concatmap (uncurry replicate) -- g2 :: [(Int,a)] -> [a] -- g2 dada una lista de pares [(n1,e1),(n2,e2),..] produce la lista formada por n1 veces e1, -- n2 veces e2, etc. -- d) -- g2 [(2,'a'),(3,'b'),(5,'c')] produce "aabbbccccc" :: [Char] -- e) -- g2 [(2,'a')] -- => concatmap (uncurry replicate) [(2,'a')] -- => concat . (map (uncurry replicate)) [(2,'a')] -- => concat ( (map (uncurry replicate)) [(2,'a')] ) -- => foldr (++) [] ( (map (uncurry replicate)) [(2,'a')] ) -- => foldr (++) [] ( (map (uncurry replicate)) ((2,'a'):[]) ) -- => foldr (++) [] ( (uncurry replicate (2,'a')):(map (uncurry replicate) []) ) -- => (uncurry replicate (2,'a')) ++ (foldr (++) [] ( (map (uncurry replicate) []) )) -- => (++) (replicate 2 'a') (foldr (++) [] ( (map (uncurry replicate) []) )) -- => (++) ((take 2 (repeat 'a')) (foldr (++) [] ( (map (uncurry replicate) []) )) -- aqui aparece la extructura cíclica que produce (repeat 'a') -- (faltan las flechas, hay que hacerlas a mano) -- => (++) ((take 2 ( 'a': @ )) (foldr (++) [] ( (map (uncurry replicate) []) )) -- => (++) ( 'a': (take 1 ( 'a': @ )) (foldr (++) [] ( (map (uncurry replicate) []) )) -- => 'a': ((++) (take 1 ( 'a': @ )) (foldr (++) [] ( (map (uncurry replicate) []) )) -- => 'a': ((++) ( 'a':(take 0 ( 'a': @ )) (foldr (++) [] ( (map (uncurry replicate) []) )) -- => 'a': 'a': ((++) (take 0 ( 'a': @ )) (foldr (++) [] ( (map (uncurry replicate) []) )) -- => 'a': 'a': ((++) [] (foldr (++) [] ( (map (uncurry replicate) []) )) -- => 'a': 'a': (foldr (++) [] ( (map (uncurry replicate) []) )) -- => 'a': 'a': (foldr (++) [] []) -- => 'a': 'a': [] -- => "aa":: String -- f) concatmap' f = foldr (g f) [] where g f x1 x2 = f x1 ++ x2