Universidad Simón Bolı́var Departamento de Computación y Tecnologı́a de la Información. CI–3661 – Laboratorio de Lenguajes de Programación. Septiembre–Diciembre 2012 Quiz I: Haskell – Solución (15 pts) 0. (4.5 pts – 0.75 pts c/u) – Para cada una de las siguientes expresiones en Haskell, infiera su tipo más general. Por ejemplo: El tipo de 2 + 3 serı́a (Num a) => a El tipo de (\x -> True:x) serı́a [Bool] -> [Bool] El tipo de (\x y -> x < y) serı́a (Ord a) => a -> a -> Bool a) "Hola quiz!" String b) (True, [1, 2, 3]) (Num a) => (Bool, [a]) c) length [1..] Int d) map product (Num b) => [[b]] -> [b] e) foldr (:) "origami" String -> String f) [ \x y -> show x ++ show y, \a b -> if a < b then "menor" else "mayor", \s _ -> show s ] (Show a, Ord a) => [a -> a -> String] g) const (+7) (Extra - 0.5pts) (Num a) => b -> a -> a h) \f -> let x = f x in x (Extra - 0.5pts) (a -> a) -> a i) foldl (>>=) [] (Extra - 0.5pts) [a -> [a]] -> [a] j) Considerando la definición: data Arbol a = Hoja a | Rama a (Arbol a) (Arbol a) (Extra - 0.5pts) \x -> Rama (Rama True x x) (Hoja (Hoja False)) (Hoja x) Arbol Bool -> Arbol (Arbol Bool) 1 1. (4.5 pts – 0.75 pts c/u) – Evalúe cada una de las siguientes expresiones en Haskell. Por ejemplo: La evaluación de 2 + 3 serı́a 5 La evaluación de (\x -> True:x) [False, True] serı́a [True, False, True] La evaluación de (\x y -> x < y) 3 2 serı́a False a) id 7 7 b) take 5 [1,3..] [1, 3, 5, 7, 9] c) zip [1,2,3] "abcdef" [(1, ’a’), (2, ’b’), (3, ’c’)] d) sum $ zipWith (*) [1, 1, 3, 7] [1, 2, 3, 5] 47 e) let f x [] = [x] f x (y:ys) = if x < y then x : y : ys else y : f x ys in foldr f [] [3,1,5,2,4,7,6] [1, 2, 3, 4, 5, 6, 7] f) Just 523 >>= \y -> return ("ci" ++ show (y * 7)) Just "ci3661" g) zipWith id [(+1), (+2), (+3)] [1..] (Extra - 0.5pts) [2, 4, 6] h) [1,2,3] >>= \y -> [y..2*y] (Extra - 0.5pts) [1, 2, 2, 3, 4, 3, 4, 5, 6] i) let pp = scanl (+) 1 pp in take 10 pp (Extra - 0.5pts) [1, 2, 4, 8, 16, 32, 64, 128, 256, 512] j) Considerando la definición: data Arbol a = Hoja a | Rama a (Arbol a) (Arbol a) (Extra - 0.5pts) (\f (Rama x (Hoja y) z) -> x + y + f z) (const 1) (Rama 3 (Hoja 3) (Hoja 5)) 7 2 2. (6 pts) – Implemente las siguientes funciones en Haskell. Nota: Use solo funciones de orden superior y/o listas por comprensión para optar a la nota completa. Puede usar recursión (ya sea simple o de cola) por un máximo del 50 % de la misma. a) (1 pt) – Implemente una función insertar :: a -> [a] -> Int -> [a], que tome un elemento x, una lista xs y un entero k; y devuelve la misma lista xs con el elemento x insertado en la k–ésima posición. (puede suponer 0 ≤ k ≤ length xs). Por ejemplo: insertar ‘Z’ "abcde" 3 = "abcZde" insertar x xs k = take k xs ++ x : drop k xs b) (1.5 pts) – Implemente una función multiInsertar :: a -> [a] -> [[a]], que toma un elemento x y una lista xs; y devuelve un lista de listas conteniendo la misma lista xs con el elemento x insertado en cada posible posición. Por ejemplo: multiInsertar ‘Z’ "abcde" = ["Zabcde", "aZbcde", "abZcde", "abcZde", "abcdZe", "abcdeZ"] multiInsertar x xs = map (insertar x xs) [0..length xs] c) (1.5 pts) – Implemente una función aumentar :: a -> [[a]] -> [[a]], que toma un elemento x y una lista de listas xs; y devuelve un lista de listas conteniendo las mismas listas en xs con el elemento x insertado en cada posible posición. Por ejemplo: aumentar 1 [[2,3], [3,4]] = [[1,2,3],[2,1,3],[2,3,1],[1,3,4],[3,1,4],[3,4,1]] aumentar = concatMap . multiInsertar d) (2 pts) – Implemente una función permuts :: [a] -> [[a]], que toma un elemento una lista xs; y devuelve un lista de listas conteniendo todas las posibles permutaciones de xs. Por ejemplo: permuts [1,2,3] = [[1,2,3],[2,1,3],[2,3,1],[1,3,2],[3,1,2],[3,2,1]] permuts = foldr aumentar [[]] 3