{"id":5179,"date":"2015-11-20T19:08:12","date_gmt":"2015-11-20T18:08:12","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=5179"},"modified":"2015-11-21T19:09:11","modified_gmt":"2015-11-21T18:09:11","slug":"i1m2015-funciones-de-orden-superior-y-definiciones-por-plegados","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2015-funciones-de-orden-superior-y-definiciones-por-plegados\/","title":{"rendered":"I1M2015: Funciones de orden superior y definiciones por plegados"},"content":{"rendered":"<p>En la primera parte de la clase de hoy de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-15\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> hemos comentado las soluciones a los ejercicios de la relaci\u00f3n 10 sobre Funciones de orden superior y definiciones por plegados.<\/p>\n<p>Los ejercicios y su soluci\u00f3n se muestran a continuaci\u00f3n<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\n-- ---------------------------------------------------------------------\n-- Introducci\u00f3n                                                       --\n-- ---------------------------------------------------------------------\n\n-- Esta relaci\u00f3n tiene contiene ejercicios con funciones de orden\n-- superior y definiciones por plegado correspondientes al tema 7 \n-- http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-15\/temas\/tema-7.html\n\n-- ---------------------------------------------------------------------\n-- Importaci\u00f3n de librer\u00edas auxiliares                                --\n-- ---------------------------------------------------------------------\n\nimport Test.QuickCheck\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1.1. Definir, por recursi\u00f3n, la funci\u00f3n\n--    takeWhileR :: (a -> Bool) -> [a] -> [a]\n-- tal que (takeWhileR p xs) es la lista de los elemento de xs hasta el\n-- primero que no cumple la propiedad p. Por ejemplo,\n--    takeWhileR (<7) [2,3,9,4,5]  ==  [2,3]\n-- ---------------------------------------------------------------------\n\ntakeWhileR :: (a -> Bool) -> [a] -> [a]\ntakeWhileR _ [] = []\ntakeWhileR p (x:xs) \n    | p x       = x : takeWhileR p xs\n    | otherwise = []\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1.2. Comprobar con QuickCheck que, para cualquier lista de\n-- enteros xs, se verifica que (takeWhileR even xs) es igual que \n-- (takeWhile even xs)\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_takeWhileR :: [Int] -> Bool\nprop_takeWhileR xs =\n    takeWhileR even xs == takeWhile even xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_takeWhile\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1.3. Comprobar con QuickCheck que, para cualquier lista de\n-- enteros xs, se verifica que todos los elementos de (takeWhileR even xs)\n-- son pares.\n-- ---------------------------------------------------------------------\n\nprop_takeWhileTodos :: [Int] -> Bool\nprop_takeWhileTodos xs =\n    all even (takeWhileR even xs)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.1. Definir por recursi\u00f3n la funci\u00f3n\n--    dropWhileR :: (a -> Bool) -> [a] -> [a]\n-- tal que (dropWhileR p xs) es la lista de eliminando los elemento de xs\n-- hasta el primero que cumple la propiedad p. Por ejemplo,\n--    dropWhileR (<7) [2,3,9,4,5]  ==  [9,4,5]\n-- ---------------------------------------------------------------------\n\ndropWhileR :: (a -> Bool) -> [a] -> [a]\ndropWhileR _ [] = []\ndropWhileR p (x:xs)\n    | p x       = dropWhileR p xs\n    | otherwise = x:xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.2. Comprobar con QuickCheck que, para cualquier lista de\n-- enteros xs, se verifica que la concatenaci\u00f3n de (takeWhileR even xs)\n-- y (dropWhileR even xs) es igual a xs.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_takeDrop :: [Int] -> Bool\nprop_takeDrop xs =\n    takeWhileR even xs ++ dropWhileR even xs == xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_takeDrop\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.1. Definir, por comprensi\u00f3n, la funci\u00f3n\n--    divideMediaC :: [Double] -> ([Double],[Double])\n-- tal que (divideMediaC xs) es el par (ys,zs), donde ys contiene los\n-- elementos de xs estrictamente menores que la media, mientras que zs\n-- contiene los elementos de xs estrictamente mayores que la media. Por\n-- ejemplo,  \n--    divideMediaC [6,7,2,8,6,3,4] ==  ([2.0,3.0,4.0],[6.0,7.0,8.0,6.0])\n--    divideMediaC [1,2,3]         ==  ([1.0],[3.0])\n-- ---------------------------------------------------------------------\n\ndivideMediaC :: [Double] -> ([Double],[Double])\ndivideMediaC xs = ([x | x <- xs, x < m], [x | x <- xs, x > m])\n    where m = media xs\n\n-- (media xs) es la media de xs. Por ejemplo,\n--    media [1,2,3]       ==  2.0\n--    media [1,-2,3.5,4]  ==  1.625 \nmedia :: [Double] -> Double\nmedia xs = (sum xs) \/ fromIntegral (length xs)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.2. Definir, con filter, la funci\u00f3n\n--    divideMediaF :: [Double] -> ([Double],[Double])\n-- tal que (divideMediaF xs) es el par (ys,zs), donde ys contiene los\n-- elementos de xs estrictamente menores que la media, mientras que zs\n-- contiene los elementos de xs estrictamente mayores que la media. Por\n-- ejemplo,  \n--    divideMediaF [6,7,2,8,6,3,4] ==  ([2.0,3.0,4.0],[6.0,7.0,8.0,6.0])\n--    divideMediaF [1,2,3]         ==  ([1.0],[3.0])\n-- ---------------------------------------------------------------------\n\ndivideMediaF :: [Double] -> ([Double],[Double])\ndivideMediaF xs = (filter (<m) xs, filter (>m) xs)\n    where m = media xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.3. Definir, por recursi\u00f3n, la funci\u00f3n\n--    divideMediaR :: [Double] -> ([Double],[Double])\n-- tal que (divideMediaR xs) es el par (ys,zs), donde ys contiene los\n-- elementos de xs estrictamente menores que la media, mientras que zs\n-- contiene los elementos de xs estrictamente mayores que la media. Por\n-- ejemplo,  \n--    divideMediaR [6,7,2,8,6,3,4] ==  ([2.0,3.0,4.0],[6.0,7.0,8.0,6.0])\n--    divideMediaR [1,2,3]         ==  ([1.0],[3.0])\n-- ---------------------------------------------------------------------\n\ndivideMediaR :: [Double] -> ([Double],[Double])\ndivideMediaR xs = divideMediaR' xs\n    where m = media xs\n          divideMediaR' [] = ([],[])\n          divideMediaR' (x:xs) | x < m  = (x:ys, zs)\n                               | x == m = (ys, zs)\n                               | x > m  = (ys, x:zs)\n                               where (ys, zs) = divideMediaR' xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.4. Comprobar con QuickCheck que las tres definiciones\n-- anteriores divideMediaF, divideMediaC y divideMediaR son\n-- equivalentes.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_divideMedia :: [Double] -> Bool\nprop_divideMedia xs =\n    divideMediaC xs == d &&\n    divideMediaR xs == d\n    where d = divideMediaF xs \n    \n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_divideMedia\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.5. Comprobar con QuickCheck que si (ys,zs) es el par\n-- obtenido aplic\u00e1ndole la funci\u00f3n divideMediaF a xs, entonces la suma\n-- de las longitudes de ys y zs es menor o igual que la longitud de xs.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_longitudDivideMedia :: [Double] -> Bool\nprop_longitudDivideMedia xs =\n    length ys + length zs <= length xs\n    where (ys,zs) = divideMediaF xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_longitudDivideMedia\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.6. Comprobar con QuickCheck que si (ys,zs) es el par\n-- obtenido aplic\u00e1ndole la funci\u00f3n divideMediaF a xs, entonces todos los\n-- elementos de ys son menores que todos los elementos de zs.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_divideMediaMenores :: [Double] -> Bool\nprop_divideMediaMenores xs =\n    and [y < z | y <- ys, z <- zs]\n    where (ys,zs) = divideMediaF xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_divideMediaMenores\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.7. Comprobar con QuickCheck que si (ys,zs) es el par\n-- obtenido aplic\u00e1ndole la funci\u00f3n divideMediaF a xs, entonces la\n-- media de xs no pertenece a ys ni a zs.\n-- \n-- Nota: Usar la funci\u00f3n notElem tal que (notElem x ys) se verifica si y\n-- no pertenece a ys.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_divideMediaSinMedia :: [Double] -> Bool\nprop_divideMediaSinMedia xs =\n    notElem m (ys ++ zs)\n    where  m       = media xs\n           (ys,zs) = divideMediaF xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_divideMediaSinMedia\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4. Definir la funci\u00f3n\n--    segmentos :: (a -> Bool) -> [a] -> [a]\n-- tal que (segmentos p xs) es la lista de los segmentos de xs cuyos\n-- elementos verifican la propiedad p. Por ejemplo,\n--    segmentos even [1,2,0,4,9,6,4,5,7,2]  ==  [[2,0,4],[6,4],[2]]\n--    segmentos odd  [1,2,0,4,9,6,4,5,7,2]  ==  [[1],[9],[5,7]]\n-- ---------------------------------------------------------------------\n\nsegmentos :: (a -> Bool) -> [a] -> [[a]]\nsegmentos p [] = []\nsegmentos p (x:xs) \n    | p x       = takeWhile p (x:xs) : segmentos p (dropWhile p xs)\n    | otherwise = segmentos p xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5.1. Definir, por comprensi\u00f3n, la funci\u00f3n\n--    relacionadosC :: (a -> a -> Bool) -> [a] -> Bool\n-- tal que (relacionadosC r xs) se verifica si para todo par (x,y) de\n-- elementos consecutivos de xs se cumple la relaci\u00f3n r. Por ejemplo,\n--    relacionadosC (<) [2,3,7,9]                ==  True\n--    relacionadosC (<) [2,3,1,9]                ==  False\n-- ---------------------------------------------------------------------\n\nrelacionadosC :: (a -> a -> Bool) -> [a] -> Bool\nrelacionadosC r xs = and [r x y | (x,y) <- zip xs (tail xs)]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5.1. Definir, por comprensi\u00f3n, la funci\u00f3n\n--    relacionadosR :: (a -> a -> Bool) -> [a] -> Bool\n-- tal que (relacionadosR r xs) se verifica si para todo par (x,y) de\n-- elementos consecutivos de xs se cumple la relaci\u00f3n r. Por ejemplo,\n--    relacionadosR (<) [2,3,7,9]                ==  True\n--    relacionadosR (<) [2,3,1,9]                ==  False\n-- ---------------------------------------------------------------------\n\nrelacionadosR :: (a -> a -> Bool) -> [a] -> Bool\nrelacionadosR r (x:y:zs) = (r x y) && relacionadosR r (y:zs)\nrelacionadosR _ _ = True\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6.1. Definir la funci\u00f3n\n--    agrupa :: Eq a => [[a]] -> [[a]]\n-- tal que (agrupa xss) es la lista de las listas obtenidas agrupando\n-- los primeros elementos, los segundos, ... Por ejemplo, \n--    agrupa [[1..6],[7..9],[10..20]]  ==  [[1,7,10],[2,8,11],[3,9,12]]\n--    agrupa []                        ==  []\n-- ---------------------------------------------------------------------\n\nagrupa :: Eq a => [[a]] -> [[a]]\nagrupa []  = []\nagrupa xss\n    | [] `elem` xss = []\n    | otherwise     = primeros xss : agrupa (restos xss)\n    where primeros = map head\n          restos   = map tail\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6.2. Comprobar con QuickChek que la longitud de todos los\n-- elementos de (agrupa xs) es igual a la longitud de xs.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_agrupa :: [[Int]] -> Bool\nprop_agrupa xss =\n    and [length xs == n | xs <- agrupa xss]\n    where n = length xss\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_agrupa\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.1. Definir por recursi\u00f3n la funci\u00f3n\n--    superparR :: Int -> Bool\n-- tal que (superparR n) se verifica si n es un n\u00famero par tal que todos\n-- sus d\u00edgitos son pares. Por ejemplo,\n--    superparR 426  ==  True\n--    superparR 456  ==  False\n-- ---------------------------------------------------------------------\n\nsuperparR :: Int -> Bool\nsuperparR 0 = True\nsuperparR n = even n && superparR (div n 10)  \n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.2. Definir por comprensi\u00f3n la funci\u00f3n\n--    superparC :: Int -> Bool\n-- tal que (superparC n) se verifica si n es un n\u00famero par tal que todos\n-- sus d\u00edgitos son pares. Por ejemplo,\n--    superparC 426  ==  True\n--    superparC 456  ==  False\n-- ---------------------------------------------------------------------\n\nsuperparC :: Int -> Bool\nsuperparC n = and [even d | d <- digitos n]\n\ndigitos :: Int -> [Int]\ndigitos n = [read [d] | d <- show n]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.3. Definir, por recursi\u00f3n sobre los d\u00edgitos, la funci\u00f3n\n--    superparRD :: Int -> Bool\n-- tal que (superparRD n) se verifica si n es un n\u00famero par tal que todos\n-- sus d\u00edgitos son pares. Por ejemplo,\n--    superparRD 426  ==  True\n--    superparRD 456  ==  False\n-- ---------------------------------------------------------------------\n\nsuperparRD :: Int -> Bool\nsuperparRD n = sonPares (digitos n)\n    where sonPares []     = True\n          sonPares (d:ds) = even d && sonPares ds\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.4. Definir, usando all, la funci\u00f3n\n--    superparA :: Int -> Bool\n-- tal que (superparA n) se verifica si n es un n\u00famero par tal que todos\n-- sus d\u00edgitos son pares. Por ejemplo,\n--    superparA 426  ==  True\n--    superparA 456  ==  False\n-- ---------------------------------------------------------------------\n\nsuperparA :: Int -> Bool\nsuperparA n = all even (digitos n)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.5. Definir, usando filter, la funci\u00f3n\n--    superparF :: Int -> Bool\n-- tal que (superparF n) se verifica si n es un n\u00famero par tal que todos\n-- sus d\u00edgitos son pares. Por ejemplo,\n--    superparF 426  ==  True\n--    superparF 456  ==  False\n-- ---------------------------------------------------------------------\n\nsuperparF :: Int -> Bool\nsuperparF n = filter even (digitos n) == digitos n\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.1. Definir, por recursi\u00f3n, la funci\u00f3n \n--    concatR :: [[a]] -> [a]\n-- tal que (concatR xss) es la concatenaci\u00f3n de las listas de xss. Por\n-- ejemplo, \n--    concatR [[1,3],[2,4,6],[1,9]]  ==  [1,3,2,4,6,1,9]\n-- ---------------------------------------------------------------------\n\nconcatR :: [[a]] -> [a]\nconcatR _       = []\nconcatR (xs:xss) = xs ++ concatR xss\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.2. Definir, usando foldr, la funci\u00f3n \n--    concatP :: [[a]] -> [a]\n-- tal que (concatP xss) es la concatenaci\u00f3n de las listas de xss. Por\n-- ejemplo, \n--    concatP [[1,3],[2,4,6],[1,9]]  ==  [1,3,2,4,6,1,9]\n-- ---------------------------------------------------------------------\n\nconcatP :: [[a]] -> [a]\nconcatP = foldr (++) []\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.3. Comprobar con QuickCheck que la funciones concatR,\n-- concatP y concat son equivalentes.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_concat :: [[Int]] -> Bool\nprop_concat xss =\n    concatR xss == ys && concatP xss == ys\n    where ys = concat xss\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_concat\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.4. Comprobar con QuickCheck que la longitud de \n-- (concatP xss) es la suma de las longitudes de los elementos de xss.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_longConcat :: [[Int]] -> Bool\nprop_longConcat xss =\n    length (concatP xss) == sum [length xs | xs <- xss]\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_longConcat\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.1. Definir, por comprensi\u00f3n, la funci\u00f3n\n--    filtraAplicaC :: (a -> b) -> (a -> Bool) -> [a] -> [b]\n-- tal que (filtraAplicaC f p xs) es la lista obtenida aplic\u00e1ndole a los\n-- elementos de xs que cumplen el predicado p la funci\u00f3n f. Por ejemplo,\n--    filtraAplicaC (4+) (<3) [1..7]  =>  [5,6]\n-- ---------------------------------------------------------------------\n\nfiltraAplicaC :: (a -> b) -> (a -> Bool) -> [a] -> [b]\nfiltraAplicaC f p xs = [f x | x <- xs, p x]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.2. Definir, usando map y filter, la funci\u00f3n\n--    filtraAplicaMF :: (a -> b) -> (a -> Bool) -> [a] -> [b]\n-- tal que (filtraAplicaMF f p xs) es la lista obtenida aplic\u00e1ndole a los\n-- elementos de xs que cumplen el predicado p la funci\u00f3n f. Por ejemplo,\n--    filtraAplicaMF (4+) (<3) [1..7]  =>  [5,6]\n-- ---------------------------------------------------------------------\n\nfiltraAplicaMF :: (a -> b) -> (a -> Bool) -> [a] -> [b]\nfiltraAplicaMF f p xs = map f (filter p xs)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.3. Definir, por recursi\u00f3n, la funci\u00f3n\n--    filtraAplicaR :: (a -> b) -> (a -> Bool) -> [a] -> [b]\n-- tal que (filtraAplicaR f p xs) es la lista obtenida aplic\u00e1ndole a los\n-- elementos de xs que cumplen el predicado p la funci\u00f3n f. Por ejemplo,\n--    filtraAplicaR (4+) (<3) [1..7]  =>  [5,6]\n-- ---------------------------------------------------------------------\n\nfiltraAplicaR :: (a -> b) -> (a -> Bool) -> [a] -> [b]\nfiltraAplicaR f p [] = []\nfiltraAplicaR f p (x:xs) | p x       = f x : filtraAplicaR f p xs\n                         | otherwise = filtraAplicaR f p xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.4. Definir, por plegado, la funci\u00f3n\n--    filtraAplicaP :: (a -> b) -> (a -> Bool) -> [a] -> [b]\n-- tal que (filtraAplicaP f p xs) es la lista obtenida aplic\u00e1ndole a los\n-- elementos de xs que cumplen el predicado p la funci\u00f3n f. Por ejemplo,\n--    filtraAplicaP (4+) (<3) [1..7]  =>  [5,6]\n-- ---------------------------------------------------------------------\n\nfiltraAplicaP :: (a -> b) -> (a -> Bool) -> [a] -> [b]\nfiltraAplicaP f p = foldr g []\n    where g x y | p x       = f x : y\n                | otherwise = y\n\n-- La definici\u00f3n por plegado usando lambda es\nfiltraAplicaP2 :: (a -> b) -> (a -> Bool) -> [a] -> [b]\nfiltraAplicaP2 f p = \n    foldr (\\x y -> if p x then (f x : y) else y) []\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10.1. Definir, mediante recursi\u00f3n, la funci\u00f3n\n--    maximumR :: Ord a => [a] -> a\n-- tal que (maximumR xs) es el m\u00e1ximo de la lista xs. Por ejemplo,\n--    maximumR [3,7,2,5]                  ==  7\n--    maximumR [\"todo\",\"es\",\"falso\"]      ==  \"todo\"\n--    maximumR [\"menos\",\"alguna\",\"cosa\"]  ==  \"menos\"\n-- \n-- Nota: La funci\u00f3n maximumR es equivalente a la predefinida maximum.\n-- ---------------------------------------------------------------------\n\nmaximumR :: Ord a => [a] -> a\nmaximumR [x]      = x\nmaximumR (x:y:ys) = max x (maximumR (y:ys))\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10.2. La funci\u00f3n de plegado foldr1 est\u00e1 definida por \n--    foldr1 :: (a -> a -> a) -> [a] -> a\n--    foldr1 _ [x]    =  x\n--    foldr1 f (x:xs) =  f x (foldr1 f xs)\n-- \n-- Definir, mediante plegado con foldr1, la funci\u00f3n\n--    maximumP :: Ord a => [a] -> a\n-- tal que (maximumR xs) es el m\u00e1ximo de la lista xs. Por ejemplo,\n--    maximumP [3,7,2,5]                  ==  7\n--    maximumP [\"todo\",\"es\",\"falso\"]      ==  \"todo\"\n--    maximumP [\"menos\",\"alguna\",\"cosa\"]  ==  \"menos\"\n-- \n-- Nota: La funci\u00f3n maximumP es equivalente a la predefinida maximum.\n-- ---------------------------------------------------------------------\n\nmaximumP :: Ord a => [a] -> a\nmaximumP = foldr1 max\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10.3. Comprobar con QuickCheck que, para cualquier lista no\n-- vac\u00eda xs, (maximumP xs) es un elemento de xs que es mayor o igual que\n-- todos los elementos de xs. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_maximumP :: [Int] -> Property\nprop_maximumP xs = \n    xs \/= [] ==> m `elem` xs && all (<=m) xs\n    where m = maximumP xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_maximumP\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.1. Definir, mediante plegado con foldr1, la funci\u00f3n\n--    minimunP :: Ord a => [a] -> a\n-- tal que (minimunR xs) es el m\u00e1ximo de la lista xs. Por ejemplo,\n--    minimunP [3,7,2,5]                  ==  2\n--    minimumP [\"todo\",\"es\",\"falso\"]      ==  \"es\"\n--    minimumP [\"menos\",\"alguna\",\"cosa\"]  ==  \"alguna\"\n-- \n-- Nota: La funci\u00f3n minimunP es equivalente a la predefinida minimun.\n-- ---------------------------------------------------------------------\n\nminimumP :: Ord a => [a] -> a\nminimumP = foldr1 min\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.2. Comprobar con QuickCheck que, para cualquier lista no\n-- vac\u00eda xs, (minimumP xs) es un elemento de xs que es menor o igual que\n-- todos los elementos de xs. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_minimumP :: [Int] -> Property\nprop_minimumP xs = \n    xs \/= [] ==> m `elem` xs && all (>=m) xs\n    where m = minimumP xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_minimumP\n--    +++ OK, passed 100 tests.\n<\/pre>\n<p>El c\u00f3digo correspondiente se encuentra en <a href=\"http:\/\/bit.ly\/1kNPATh\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En la primera parte de la clase de hoy de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas hemos comentado las soluciones a los ejercicios de la relaci\u00f3n 10 sobre Funciones de orden superior y definiciones por plegados. Los ejercicios y su soluci\u00f3n se muestran a continuaci\u00f3n<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[250],"tags":[270,310],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5179"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/comments?post=5179"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5179\/revisions"}],"predecessor-version":[{"id":5180,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5179\/revisions\/5180"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=5179"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=5179"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=5179"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}