{"id":2496,"date":"2013-01-24T19:12:12","date_gmt":"2013-01-24T19:12:12","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=2496"},"modified":"2013-03-08T05:47:34","modified_gmt":"2013-03-08T05:47:34","slug":"i1m2012-funciones-de-orden-superior-3","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2012-funciones-de-orden-superior-3\/","title":{"rendered":"I1M2012: Funciones de orden superior (3)"},"content":{"rendered":"<p>En la clase de hoy de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-12\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> hemos continuado comentando las soluciones de los ejercicios de las relaciones <a href=\"https:\/\/www.glc.us.es\/~jalonso\/ejerciciosI1M2012G2\/images\/e\/e4\/Rel_14.hs\">14<\/a> y <a href=\"https:\/\/www.glc.us.es\/~jalonso\/ejerciciosI1M2012G2\/images\/b\/b9\/Rel_15.hs\">15<\/a> (de funciones de orden superior).<\/p>\n<p>Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n. Los de la relaci\u00f3n 14:<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\r\n-- ---------------------------------------------------------------------\r\n-- Importaci\u00f3n de librer\u00edas auxiliares                                --\r\n-- ---------------------------------------------------------------------\r\n\r\nimport Test.QuickCheck\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8.1. Definir por recursi\u00f3n la funci\u00f3n\r\n--    superpar :: Int -&gt; Bool\r\n-- tal que (superpar n) se verifica si n es un n\u00famero par tal que todos\r\n-- sus d\u00edgitos son pares. Por ejemplo,\r\n--    superpar 426  ==  True\r\n--    superpar 456  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nsuperpar :: Int -&gt; Bool\r\nsuperpar n | n &lt; 10    = even n            | otherwise = even n &amp;&amp; superpar (n `div` 10) -- Otra forma equivalente es superpar' :: Int -&gt; Bool\r\nsuperpar' 0 = True\r\nsuperpar' n = even n &amp;&amp; superpar' (div n 10)  \r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8.2. Definir por comprensi\u00f3n la funci\u00f3n\r\n--    superpar2 :: Int -&gt; Bool\r\n-- tal que (superpar2 n) se verifica si n es un n\u00famero par tal que todos\r\n-- sus d\u00edgitos son pares. Por ejemplo,\r\n--    superpar2 426  ==  True\r\n--    superpar2 456  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nsuperpar2 :: Int -&gt; Bool\r\nsuperpar2 n = and [even d | d &lt;- digitos n] digitos :: Int -&gt; [Int]\r\ndigitos n = [read [d] | d &lt;- show n] -- --------------------------------------------------------------------- -- Ejercicio 8.3. Definir, por recursi\u00f3n sobre los d\u00edgitos, la funci\u00f3n --    superpar3 :: Int -&gt; Bool\r\n-- tal que (superpar3 n) se verifica si n es un n\u00famero par tal que todos\r\n-- sus d\u00edgitos son pares. Por ejemplo,\r\n--    superpar3 426  ==  True\r\n--    superpar3 456  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nsuperpar3 :: Int -&gt; Bool\r\nsuperpar3 n = sonPares (digitos n)\r\n    where sonPares []     = True\r\n          sonPares (d:ds) = even d &amp;&amp; sonPares ds\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8.3. Definir, usando all, la funci\u00f3n\r\n--    superpar4 :: Int -&gt; Bool\r\n-- tal que (superpar4 n) se verifica si n es un n\u00famero par tal que todos\r\n-- sus d\u00edgitos son pares. Por ejemplo,\r\n--    superpar4 426  ==  True\r\n--    superpar4 456  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nsuperpar4 :: Int -&gt; Bool\r\nsuperpar4 n = all even (digitos n)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8.5. Definir, usando filter, la funci\u00f3n\r\n--    superpar5 :: Int -&gt; Bool\r\n-- tal que (superpar5 n) se verifica si n es un n\u00famero par tal que todos\r\n-- sus d\u00edgitos son pares. Por ejemplo,\r\n--    superpar5 426  ==  True\r\n--    superpar5 456  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nsuperpar5 :: Int -&gt; Bool\r\nsuperpar5 n = filter even (digitos n) == digitos n\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 9. Se considera la funci\u00f3n\r\n--    filtraAplica :: (a -&gt; b) -&gt; (a -&gt; Bool) -&gt; [a] -&gt; [b]\r\n-- tal que (filtraAplica f p xs) es la lista obtenida aplic\u00e1ndole a los\r\n-- elementos de xs que cumplen el predicado p la funci\u00f3n f. Por ejemplo,\r\n--    filtraAplica (4+) (&lt;3) [1..7]  =&gt;  [5,6]\r\n-- Se pide, definir la funci\u00f3n\r\n-- 1. por comprensi\u00f3n,\r\n-- 2. usando map y filter,\r\n-- 3. por recursi\u00f3n y\r\n-- 4. por plegado (con foldr).\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La definici\u00f3n con lista de comprensi\u00f3n es\r\nfiltraAplica_1 :: (a -&gt; b) -&gt; (a -&gt; Bool) -&gt; [a] -&gt; [b]\r\nfiltraAplica_1 f p xs = [f x | x &lt;- xs, p x] -- La definici\u00f3n con map y filter es filtraAplica_2 :: (a -&gt; b) -&gt; (a -&gt; Bool) -&gt; [a] -&gt; [b]\r\nfiltraAplica_2 f p xs = map f (filter p xs)\r\n\r\n-- La definici\u00f3n por recursi\u00f3n es\r\nfiltraAplica_3 :: (a -&gt; b) -&gt; (a -&gt; Bool) -&gt; [a] -&gt; [b]\r\nfiltraAplica_3 f p [] = []\r\nfiltraAplica_3 f p (x:xs) | p x       = f x : filtraAplica_3 f p xs\r\n                          | otherwise = filtraAplica_3 f p xs\r\n\r\n-- La definici\u00f3n por plegado es\r\nfiltraAplica_4 :: (a -&gt; b) -&gt; (a -&gt; Bool) -&gt; [a] -&gt; [b]\r\nfiltraAplica_4 f p = foldr g []\r\n                     where g x y | p x       = f x : y\r\n                                 | otherwise = y\r\n\r\n-- La definici\u00f3n por plegado usando lambda es\r\nfiltraAplica_4' :: (a -&gt; b) -&gt; (a -&gt; Bool) -&gt; [a] -&gt; [b]\r\nfiltraAplica_4' f p =\r\n    foldr (\\x y -&gt; if p x then (f x : y) else y) []\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 10.1. Definir, mediante recursi\u00f3n, la funci\u00f3n\r\n--    maximumR :: Ord a =&gt; [a] -&gt; a\r\n-- tal que (maximumR xs) es el m\u00e1ximo de la lista xs. Por ejemplo,\r\n--    maximumR [3,7,2,5]  ==  7\r\n-- Nota: La funci\u00f3n maximumR es equivalente a la predefinida maximum.\r\n-- ---------------------------------------------------------------------\r\n\r\nmaximumR :: Ord a =&gt; [a] -&gt; a\r\nmaximumR [x]      = x\r\nmaximumR (x:y:ys) = max x (maximumR (y:ys))\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 10.2. La funci\u00f3n de plegado foldr1 est\u00e1 definida por\r\n--    foldr1 :: (a -&gt; a -&gt; a) -&gt; [a] -&gt; a\r\n--    foldr1 _ [x]    =  x\r\n--    foldr1 f (x:xs) =  f x (foldr1 f xs)\r\n--\r\n-- Definir, mediante plegado con foldr1, la funci\u00f3n\r\n--    maximumP :: Ord a =&gt; [a] -&gt; a\r\n-- tal que (maximumR xs) es el m\u00e1ximo de la lista xs. Por ejemplo,\r\n--    maximumP [3,7,2,5]  ==  7\r\n-- Nota: La funci\u00f3n maximumP es equivalente a la predefinida maximum.\r\n-- ---------------------------------------------------------------------\r\n\r\nmaximumP :: Ord a =&gt; [a] -&gt; a\r\nmaximumP = foldr1 max\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 11. Definir, mediante plegado con foldr1, la funci\u00f3n\r\n--    minimunP :: Ord a =&gt; [a] -&gt; a\r\n-- tal que (minimunR xs) es el m\u00e1ximo de la lista xs. Por ejemplo,\r\n--    minimunP [3,7,2,5]  ==  2\r\n-- Nota: La funci\u00f3n minimunP es equivalente a la predefinida minimun.\r\n-- ---------------------------------------------------------------------\r\n\r\nminimumP :: Ord a =&gt; [a] -&gt; a\r\nminimumP = foldr1 min<\/pre>\n<p>Los de la relaci\u00f3n 15<\/p>\n<pre lang=\"haskell\">-- ---------------------------------------------------------------------\r\n-- Importaci\u00f3n de librer\u00edas auxiliares                                --\r\n-- ---------------------------------------------------------------------\r\n\r\nimport Data.List\r\nimport Test.QuickCheck\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.1. Definir, mediante recursi\u00f3n, la funci\u00f3n\r\n--    inversaR :: [a] -&gt; [a]\r\n-- tal que (inversaR xs) es la inversa de la lista xs. Por ejemplo,\r\n--    inversaR [3,5,2,4,7]  ==  [7,4,2,5,3]\r\n-- ---------------------------------------------------------------------\r\n\r\ninversaR :: [a] -&gt; [a]\r\ninversaR []     = []\r\ninversaR (x:xs) = (inversaR xs) ++ [x]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.2. Definir, mediante plegado, la funci\u00f3n\r\n--    inversaP :: [a] -&gt; [a]\r\n-- tal que (inversaP xs) es la inversa de la lista xs. Por ejemplo,\r\n--    inversaP [3,5,2,4,7]  ==  [7,4,2,5,3]\r\n-- ---------------------------------------------------------------------\r\n\r\ninversaP :: [a] -&gt; [a]\r\ninversaP = foldr f []\r\n    where f x y = y ++ [x]\r\n\r\n-- La definici\u00f3n anterior puede simplificarse a\r\ninversaP2 :: [a] -&gt; [a]\r\ninversaP2 = foldr f []\r\n    where f x = (++ [x])\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.3. Definir, por recursi\u00f3n con acumulador, la funci\u00f3n\r\n--    inversaR' :: [a] -&gt; [a]\r\n-- tal que (inversaR' xs) es la inversa de la lista xs. Por ejemplo,\r\n--    inversaR' [3,5,2,4,7]  ==  [7,4,2,5,3]\r\n-- ---------------------------------------------------------------------\r\n\r\ninversaR' :: [a] -&gt; [a]\r\ninversaR' xs = inversaAux [] xs\r\n    where inversaAux ys []     = ys\r\n          inversaAux ys (x:xs) = inversaAux (x:ys) xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.4. La funci\u00f3n de plegado foldl est\u00e1 definida por\r\n--    foldl :: (a -&gt; b -&gt; a) -&gt; a -&gt; [b] -&gt; a\r\n--    foldl f ys xs = aux ys xs\r\n--        where aux ys []     = ys\r\n--              aux ys (x:xs) = aux (f ys x) xs\r\n-- Definir, mediante plegado con foldl, la funci\u00f3n\r\n--    inversaP' :: [a] -&gt; [a]\r\n-- tal que (inversaP' xs) es la inversa de la lista xs. Por ejemplo,\r\n--    inversaP' [3,5,2,4,7]  ==  [7,4,2,5,3]\r\n-- ---------------------------------------------------------------------\r\n\r\ninversaP' :: [a] -&gt; [a]\r\ninversaP' = foldl f []\r\n    where f ys x = x:ys\r\n\r\n-- La definici\u00f3n anterior puede simplificarse lambda:\r\ninversaP'2 :: [a] -&gt; [a]\r\ninversaP'2= foldl (\\ys x -&gt; x:ys) []\r\n\r\n-- La definici\u00f3n puede simplificarse usando flip:\r\ninversaP'3 :: [a] -&gt; [a]\r\ninversaP'3 = foldl (flip(:)) []\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.5. Comprobar con QuickCheck que las funciones reverse,\r\n-- inversaP e inversaP' son equivalentes.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_inversa :: Eq a =&gt; [a] -&gt; Bool\r\nprop_inversa xs =\r\n    inversaP xs == ys &amp;&amp;\r\n    inversaP' xs == ys\r\n    where ys = reverse xs\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci&gt; quickCheck prop_inversa\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.6. Comparar la eficiencia de inversaP e inversaP'\r\n-- calculando el tiempo y el espacio que usado en evaluar las siguientes\r\n-- expresiones:\r\n--    head (inversaP [1..100000])\r\n--    head (inversaP' [1..100000])\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La sesi\u00f3n es\r\n--    ghci&gt; :set +s\r\n--    ghci&gt; head (inversaP [1..100000])\r\n--    100000\r\n--    (0.41 secs, 20882460 bytes)\r\n--    ghci&gt; head (inversaP' [1..100000])\r\n--    1\r\n--    (0.00 secs, 525148 bytes)\r\n--    ghci&gt; :unset +s<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En la clase de hoy de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas hemos continuado comentando las soluciones de los ejercicios de las relaciones 14 y 15 (de funciones de orden superior). Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n. Los de la relaci\u00f3n 14:<\/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":[1],"tags":[298],"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\/2496"}],"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=2496"}],"version-history":[{"count":6,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/2496\/revisions"}],"predecessor-version":[{"id":2699,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/2496\/revisions\/2699"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=2496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=2496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=2496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}