Subido por gera prueba

APRENDIENDO HASKELL-EJERCICIOS Aprendiendo Haskell- Ejercicios

Anuncio
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
1 de 20
More
Create Blog
Acceder
APRENDIENDO HASKELLEJERCICIOS
miércoles, 4 de mayo de 2016
Datos personales
Aprendiendo Haskell- Ejercicios
Diego Moreno - Consultor Tecnologico
Ver todo mi perfil
Archivo del blog
Bienvenido
▼ 2016 (1)
▼ mayo (1)
En el siguiente blog podra encontrar una breve
introducciòn al mundo de haskell, para ello podra utilizar
los ejercicios y soluciones colocandolos en practica y
adentrarse a la nueva forma de programaciòn.
Aprendiendo Haskell- Ejercicios
Video introductorio ¿Que es Haskell y como se usa ?
Curso de Haskell - Aula 01 - …
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
2 de 20
Querido estudiante en esta practica encontrara diferentes ejercicios, en donde
podra colocar a prueba sus capacidades de logica matematica, para ello debera
copiar en un bloc de notas la soluciòn de los talleres punto por punto para la
ejecuciòn de estos en el software haskell
1. Redefinir las funciones del ejercicio 1 de la practica 2 usando foldr, map y filter.
2. Dada la función f = foldr (:) []
a) ¿Qué tipo tiene f?
b) Dar una definición equivalente más simple de f
3. Definir las siguientes funciones utilizando funciones de alto orden cuando sea posible:
a) pal, que determina si una cadena de caracteres es o no un palíndromo
b) hache, que cuenta la cantidad de cadenas de caracteres que comienzan con
h en una lista de cadenas
c) longmed, que calcula la longitud promedio de las listas dentro de una lista de
listas
d) doblepos, que toma una lista de enteros y devuelve la lista de los dobles de
los elementos positivos conservando el orden original
e) adyac, que toma una lista y devuelve la lista de los pares ordenados de
elementos adyacentes; por ejemplo, adyac [’a’,’b’,’c’,’d’] = [(’a’,’b’),(’b’,’c’),(’c’,’d’)]
f) difPosAdy, que toma una lista de números y devuelva la lista de los pares
ordenados de elementos adyacentes cuya diferencia es par
g) remDups, que dada una lista devuelve una lista con los mismos elementos
que la original pero eliminando todos aquellos valores que fuesen adyacentes e
iguales, dejando una sola ocurrencia. Por ejemplo, remDups [2,2,0,2,3,3,0,0,1] =
[2,0,2,3,0,1]
4. Definir las siguientes funciones:
a) takeWhile’, que devuelve el segmento inicial más largo de una lista de
elementos que verifica un predicado dado
b) takeUntil, que devuelve el segmento inicial más largo de elementos que no
verifica un predicado dado
c) dropWhile’, que devuelve el segmento de una lista de elementos que
comienza con el primer elemento que no verifica un predicado dado
5. Demostrar por inducción estructural sobre listas:
a) map (f · g) = map f · map g
b) map f (xs ++ ys) = (map f xs) ++ (map f ys)
c) (map f) · concat = concat · (map (map f))
d) filter p (xs ++ ys) = (filter p xs) ++ (filter p ys)
e) (filter p) · (filter q) = filter r where r x = (p x) && (q x)
f) reverse (xs ++ ys) = reverse ys ++ reverse xs
g) (filter p) · (map f) = (map f)·(filter (p · f))
h) map (map f) · (map (x:)) = map ((f x) :)·map (map f)
i) concat · map concat = concat·concat
6. Definir una función perms :: [a] →[[a]] tal que perms xs sea la lista de todas las
permutaciones de xs. Demostrar que map (map f) (perms xs) = perms (map f xs). ¿Para
qué puede ser ´útil esta identidad?
7. Definir una función parts :: [a] →[[a]] tal que parts xs sea la lista de todas las sublistas
de xs. (ys es una sablista de xs si existen listas as y bs tales que xs = as ++ ys ++ bs).
Demostrar que map (map f) (parts xs) = parts (map f xs). ¿Para qué puede ser ´útil esta
identidad?
8.
a) Definir un predicado noDups :: [Int] →Bool tal que noDups xs = True
solamente se
cumpla cuando xs no tiene ningún elemento repetido.
b) Definir una función sublist :: [Int] →[Int] → Bool de manera que solamente se
cumpla sublist xs ys = True cuando xs es una sublista de ys.
c) Definir una función removeDups :: [Int] →[Int] tal que removeDups xs sea una
lista
con exactamente los mismos elementos que xs pero sin repeticiones.
d) Dar una condición suficiente sobre una funci´on f :: Int →Int para que
map f (removeDups xs) = removeDups (map f xs)
9. Dar otra definición de la siguiente funci´on que no utilice la funci´on reverse:
dropTrailingZeroes :: [Int] → [Int]
dropTrailingZeroes = reverse · dropWhile (==0) · reverse
10. Definir una función splitAt :: Int →[a] → ([a],[a]) que satisfaga
splitAt n xs = (take n xs, drop n xs)
Dar otra definición en términos de foldr.
11. Definir la funci´on filter en términos de map y concat.
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
3 de 20
12. Definir una función tails :: [a] → [[a]] tal que
tails = map reverse · inits · reverse
13. Dar definiciones usando foldr de las siguientes funciones:
a) inits :: [a] →[[a]], como en la Practica 2;
b) tails :: [a] →[[a]];
c) map :: (a →b) →[a] → [b];
14. Demostrar el teorema de fusión por inducciión.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SOLUCIÒN TALLER 4:
[Ej. 1] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
....................................
suma’ :: [Int] -> Int
suma’ = foldr (+) 0
alguno’ :: [Bool] -> Bool
alguno’ = foldr (||) False
todos’ :: [Bool] -> Bool
todos’ = foldr (&&) True
codes’ :: [Char] -> [Int]
codes’ = map ord
restos’ :: Int -> [Int] -> [Int]
restos’ = \n -> map (‘mod‘ n)
cuadrados’ :: [Int] -> [Int]
cuadrados’ = map (\x -> x*x)
longitudes’ :: [[a]] -> [Int]
longitudes’ = map (length)
orden’ :: [(Int,Int)] -> [(Int,Int)]
orden’ = filter (\x -> (fst(x) > snd(x)))
pares’ :: [Int] -> [Int]
pares’ = filter (\x -> x ‘mod‘ 2 == 0)
masDe’ :: Int -> [[a]] -> [[a]]
masDe’ = \n -> filter (\x -> length x > n)
[Ej. 2] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
....................................
f :: [a] -> [a]
f = foldr (:) []
f’ :: [a] -> [a]
f’ = id
[Ej. 3] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
....................................
pal :: [Char] -> Bool
pal [] = True
pal [a] = True
pal (x:xs) = (x == head(reverse xs)) && pal (reverse(tail(reverse xs)))
hache :: [[Char]] -> Int
hache [] = 0
hache (xs:xss) = if head(xs) == ’h’ then 1 + hache xss else 0 + hache xss
longmed :: [[a]] -> Int
longmed xss = (foldr (+) 0 (map (length) xss)) ‘div‘ (length xss)
doblepos :: [Int] -> [Int]
1
doblepos xs = map (^2) (filter (>0) xs)
adyac :: [a] -> [(a,a)]
adyac [] = []
adyac [x] = []
adyac (x:xs) = [(x,head(xs))] ++ adyac xs
difPosAdy :: [Int] -> [(Int,Int)]
difPosAdy [] = []
difPosAdy [x] = []
difPosAdy (x:xs) = if mod (x - head(xs)) 2 == 0 then [(x,head(xs))] ++ difPosAdy xs else
difPosAdy xs
remDups :: [Int] -> [Int]
remDups [] = []
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
4 de 20
remDups [x] = [x]
remDups (x:xs) = if x /= head(xs) then [x] ++ remDups xs else remDups xs
[Ej. 4] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
....................................
takeWhile’ :: (a -> Bool) -> [a] -> [a]
takeWhile’ f (x:xs) = if f x then x : (takeWhile f xs) else []
takeUntil :: (a -> Bool) -> [a] -> [a]
takeUntil f (x:xs) = if (f x) == False then takeUntil f xs else []
dropWhile’ :: (a -> Bool) -> [a] -> [a]
dropWhile’ f (x:xs) = if (f x) then dropWhile’ f xs else (x:xs)
.......................................................................
......................................
Algunas funciones y sus tipos
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = x : map f xs
filter :: (a -> Bool) -> [a] -> [a]
filter f [] = []
filter f (x:xs) = if x then x:filter xs else filter xs
(.) :: (b -> c) -> (a -> b) -> a -> c
(f.g) x = f(g x)
(++) :: [a] -> [a] -> [a]
[] ++ ys = ys
(x:xs) ++ ys = x:(xs++ys)
(:) :: a -> [a] -> [a] (Primitiva)
concat :: [[a]] -> [a]
concat = foldr (++) []
reverse :: [a] -> [a]
reverse [] = []
reverse (x:xs) = reverse xs ++ [x]
2
flip :: (b -> a -> c) -> a -> b -> c
flip f x y = f y x
foldl :: (b -> a -> b) -> b -> [a] -> b
foldl f e [] = e
foldl f e (x:xs) = foldl f (f e x) xs
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f e [] = e
foldr f e (x:xs) = f x (foldr f e xs)
[Ej. 5a] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
-*- map (f.g) = map f . map g
-*- Probamos para el caso base []
map (f.g) []
= x def map
[]
map f . map g []
= x def .
map f(map g [])
= x def map
map f []
= x def map
[]
.: map (f.g) [] = map f . map g []
-*- Suponemos que vale la h.i.
map (f.g) xs = map f . map g xs
-*- Probamos para (x:xs)
map (f.g) (x:xs)
= x def map
(f.g) x : map (f.g) xs
= x h.i.
(f.g) x : map f . map g xs
= x def map
map f . (g x : map g xs)
= x def map
map f . (map g x:xs)
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
5 de 20
= x notacion
map f . map g (x:xs)
:. map (f.g) (x:xs) = map f . map g (x:xs)
:. map (f.g) = map f . map g
[Ej. 5b] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
-*- map f (xs ++ ys) = (map f xs) ++ (map f ys)
3
-*- Probamos el caso base para []
map f ([] ++ ys)
= x def ++
map f ys
(map f []) ++ (map f ys)
= x def map
[] ++ (map f ys)
= x def ++
map f ys
:. map f ([] ++ ys) = (map f []) ++ (map f ys)
-*- Suponemos que vale la h.i.
map f (xs ++ ys) = (map f xs) ++ (map f ys)
-*- Probamos para (x:xs)
map f ((x:xs) ++ ys)
= x notacion
map f (x:(xs ++ ys))
= x def map
f x : map f (xs ++ ys)
= x h.i.
f x : (map f xs) ++ (map f ys)
= x def map
map f (x:xs) ++ (map f ys)
:. map f (x:xs ++ ys) = (map f x:xs) ++ (map f ys)
:. map f (xs ++ ys) = (map f xs) ++ (map f ys)
[Ej. 5c] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
-*- (map f) . concat = concat . (map (map f))
-*- Veamos si los tipos coinciden
(.) :: (b -> c) -> (a -> b) -> a -> c
concat :: [[x]] -> [x]
Si f :: x -> z
map f :: [x] -> [z]
.: a=[[x]], b=[x], c=[z]
.: (map f) . concat :: [[x]] -> [z]
(.) :: (b -> c) -> (a -> b) -> a -> c
f :: x -> z
map (map f) :: [[x]] -> [[z]]
Si concat :: [[z]] -> [z]
.: a=[[x]], b=[[z]], c=[z]
.: concat . (map (map f)) :: [[x]] -> [z]
-*- Probamos para [[]]
4
map f . (concat [[]])
= x def .
map f (concat [[]])
= x def concat
map f []
= x def map
[]
concat . (map (map f) [[]])
= x def .
concat (map map(f) [[]])
= x def map
concat [[]]
= x def concat
[]
-*- Suponemos que vale la h.i.
(map f) . concat xss = concat . (map (map f) xss)
-*- Probamos para (xs:xss)
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
6 de 20
(map f) . concat (xs:xss)
= x def .
map f (concat (xs:xss))
= x def concat
map f (xs ++ (concat xss))
= x def map
map f xs ++ map f (concat xss)
= x h.i.
map f xs ++ concat . (map (map f) xss)
= x def .
map f xs ++ concat (map (map f) xss)
= def concat
concat ((map f) xs : map (map f) xss)
= x def map
concat (map (map f) (xs:xss))
= x def .
concat . (map (map f) (xs:xss))
:. (map f) . concat (xs:xss) = concat . (map (map f) (xs:xss))
:. (map f) . concat = concat . (map (map f))
[Ej. 5d] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
-*- filter p (xs ++ ys) = (filter p xs) ++ (filter p ys)
-*- Probamos para []
filter p ([] ++ ys)
= filter p ys
(filter p []) ++ (filter p ys)
= [] ++ (filter p ys)
5
= filter p ys
-*- Suponemos que vale la h.i.
filter p (xs ++ ys) = (filter p xs) ++ (filter p ys)
-*- Probamos para (x:xs)
filter p ((x:xs) ++ ys)
= (filter p (x:(xs ++ ys))
-*- Si p x = True
= (x : filter p (xs ++ ys))
= x : ((filter p xs) ++ (filter p ys))
-- x h.i.
= x : (filter p xs) ++ (filter p ys)
= (filter p (x:xs)) ++ (filter p ys)
-*- Si p x = False
= filter p (xs ++ ys)
-- x h.i.
= (filter p xs) ++ (filter p ys)
-- x def filter
= (filter p (x:xs)) ++ (filter p ys)
:. filter p ((x:xs) ++ ys) = (fiter p (x:xs)) ++ (filter p ys)
:. filter p (xs ++ ys) = (filter p xs) ++ (filter p ys)
[Ej. 5e] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
-*- (filter p) . (filter q) = filter r where r x = (p x) && (q x)
-*- Probamos para x = []
(filter p) . (filter q) []
= filter p (filter q [])
= filter p []
= []
filter r []
= []
-*- Suponemos valido para xs
(filter p) . (filter q) xs = filter r xs
filter p (filter q xs) = filter r xs
-*- Probamos para x:xs
(filter p) . (filter q) (x:xs)
= filter p (filter q (x:xs))
-*- Si q x == True
= filter p (x : filter q xs)
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
7 de 20
6
-*- Si p x == True
= x : (filter p (filter q xs))
-- x h.i.
= x : filter r xs
= filter r where r x = (p x) && (q x) (x:xs)
-*- Si p x == False
= filter p (filter q xs)
-- x h.i.
= filter r xs
= filter r where r x = (p x) && (q x) (x:xs)
-*- Si p x == True
= filter p (filter q xs)
-- x h.i.
= filter r xs
= filter r where r x = (p x) && (q x) (x:xs)
-*- Si q x == False
= filter p (filter q xs)
-- x h.i.
= filter r xs
= filter r where r x = (p x) && (q x) (x:xs)
.: (filter p) . (filter q) (x:xs) = filter r where r x = (p x) && (q x) (x:xs)
.: (filter p) . (filter q) = filter r where r x = (p x) && (q x)
[Ej. 5f ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
....................................
-*- reverse (xs ++ ys) = reverse ys ++ reverse xs
-*- Probamos para []
reverse ([] ++ ys)
= reverse ys
reverse ys ++ reverse []
= reverse ys ++ []
= reverse ys
-*- Probamos para (x:xs)
reverse ((x:xs) ++ ys)
= reverse (x:(xs ++ ys))
-- x def reverse
= reverse (xs ++ ys) ++ [x]
-- x h.i.
= reverse ys ++ reverse xs ++ x
-- x def reverse
= reverse ys ++ reverse (x:xs)
.: reverse ((x:xs) ++ ys) = reverse ys ++ reverse (x:xs)
.: reverse (xs ++ ys) = reverse ys ++ reverse xs
[Ej. 5g] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
7
-*- (filter p) . (map f) = (map f) . (filter (p . f))
Nos fijamos si coinciden los tipos
(.) :: (b -> c) -> (a -> b) -> a -> c
Si f :: x -> y
map f :: [x] -> [y]
filter p :: [y] -> [y]
.: p :: y -> Bool
.: a=[x], b=[y], c=[y]
.: (filter p) . (map f) :: [x] -> [y]
(.) :: (b -> c) -> (a -> b) -> a -> c
Si f :: x -> y
p :: y -> Bool
.: a=[x], b=[y], c=[Bool]
.: (p . f) :: x -> Bool
.: filter (p . f) :: [x] -> [x]
map f :: [x] -> [y]
(.) :: (b1 -> c1) -> (a1 -> b1) -> a1 -> c1
.: a1=[x], b1=[x], c1=[y]
.: (map f) . (filter (p . f)) :: [x] -> [y]
-*- Probamos para []
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
8 de 20
(filter p) . (map f) []
= filter p (map f [])
= filter p []
= []
(map f) . (filter (p . f)) []
= map f (filter (p . f) [])
= map f []
= []
-*- Suponemos que vale
(filter p) . (map f xs) = (map f) . (filter (p . f) xs)
-*- Probamos para (x:xs)
(filter p) . (map f) (x:xs)
= filter p (map f (x:xs))
= filter p (f x : map f xs)
-*- Si p (f x) == True
= f x : filter p (map f xs) (*)
-*- Si p (f x) == False
= filter p (map f xs) (**)
(map f) . (filter (p . f) (x:xs))
= map f (filter (p . f) (x:xs))
8
-*- Si (p . f) x == True
= map f (x : filter (p . f) xs)
= f x : map f (filter (p . f) xs)
-- x h.i
= f x : (filter p) . (map f xs)
= f x : filter p (map f xs) (*)
= filter p (map f (x:xs))
= (filter p) . (map f (x:xs))
-*- Si (p . f) x == False
= map f (filter (p . f) xs)
-- x h.i.
= (filter p) . (map f xs)
= filter p (map f xs) (**)
= filter p (map f (x:xs))
= (filter p) . (map f (x:xs))
.: (map f) . (filter (p . f) (x:xs)) = (filter p) . (map f (x:xs))
.: (filter p) . (map f) = (map f) . (filter (p . f))
[Ej. 5h] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
-*- map (map f) . (map (x:)) = map ((f x) :) map (map f)
map ((map f (map (x:)))) = map ((f x) :) map (map f)
(.) :: (b -> c) -> (a -> b) -> a -> c
map (x:) :: [[x]] -> [[x]]
map f :: [[x]] -> [[y]]
f :: [x] -> [y]
.: a = [[x]], b=[[x]], c=[[y]]
map(f) . (map (x:)) :: [[x]] -> [[y]]
-*- Probamos para el caso base [[]]
map (map f) . (map (x:)) [[]]
= map (map f (map (x:) [[]])
= map (map f [[x]]
= [[f x]]
map ((f x):) map (map f) [[]]
= map ((f x):) map (map f [[]])
= map ((f x):) map [[]]
= map ((f x):) [[]]
= [[f x]]
-*- Suponemos que vale para
map (map f) . (map (x:)) xss = map ((f x) :) map (map f) xss
-*- Probamos para (xs:xss)
map (map f) . (map (x:)) (xs:xss)
= map (map f (map (x:) xs:xss))
= map (map f (x:xs : map (x:) xss))
9
= ([[f x]] : (map (map f) xs)) : (map f (map (x:) xss))
-- x h.i.
= ([[f x]] : (map (map f) xs)) : map ((f x) :) map (map f) xss
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
9 de 20
= ([[f x]] : (map (map f) xs)) : map ((f x) :) (map (map f) xss)
= (map (map f) x:xs) : map ((f x) :) (map (map f) xss)
= ??????
[Ej. 5i] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
....................................
-*- concat . map concat = concat . concat
(.) :: (b -> c) -> (a -> b) -> a -> c
concat :: [[x]] -> [x]
.: map concat :: [[[x]]] -> [[x]]
.: a = [[[x]]], b=[[x]], c=[x]
.: concat . map concat :: [[[x]]] -> [x]
(.) :: (b -> c) -> (a -> b) -> a -> c
concat :: [[x]] -> [x]
-- Sabemos que b no puede ser [x] por que tendriamos
-- un error de tipo cuando se lo pasamos al primer concat, entonces
Si concat :: [[[x]]] -> [[x]]
.: a = [[[x]]], b=[[x]], c=[x]
.: concat . concat :: [[[x]]] -> [x]
-*- Probamos para [[[]]]
concat . map concat [[[]]]
= concat (map concat [[[]]])
= concat [[]]
= []
concat . concat [[[]]]
= concat (concat [[[]]])
= concat [[]]
= []
-*- Suponemos que vale la h.i.
concat . map concat xsss = concat . concat xsss
-*- Probamos que vale para (xss:xsss)
concat . map concat (xss:xsss)
= concat (map concat (xss:xsss))
= concat (concat xss : map concat xsss)
= concat (concat xss) ++ concat (map concat xsss)
-- x h.i.
= concat (concat xss) ++ concat . concat xsss
= concat (concat xss ++ concat xsss)
= concat (concat (xss:xsss))
= concat . concat (xss:xsss)
.: concat . map concat (xss:xsss) = concat . concat (xss:xsss)
10
.: concat . map concat = concat . concat
[Ej. 6] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
....................................
-- Esta funcion va tomando cada elemtento y crea una lista
-- te tuplas donde cada elemento tiene asociado sus listas a compararse
-- Como se repiten los casos en que se hace
-- a:(filter (a/=) [a,x1,..,xn]) == a:(filter (a/=) [x1,..,xn,a])
-- filtro los elementos unicos
--- > perms [1,2,3]
-- unicos(map fun2 concat[[(1,[1,2,3]),(1,[2,3,1]),(1,[3,2,1])],[(2,[1,2,3]),(2,[2,3,1]),...]])
-- unicos([[1,2,3],[1,2,3],[1,3,2],[2,1,3],[2,3,1],...])
-- [[1,2,3],[1,3,2],...]
perms :: Eq a => [a] -> [[a]]
perms ps = unicos(map fun2 (concat(map (\a -> fun a us (length(us))) us)))
where fun2 (x,xs) = x:(filter (x/=) xs); us = unicos ps
-- Esta funcion une un elemento con sus listas a comparar
-- en los distintos ordenes posibles, donde n es el largo de la lista
-- > fun 1 [1,2,3] 3
-- [(1,[1,2,3]),(1,[2,3,1]),(1,[3,1,2])]
fun :: a -> [a] -> Int -> [(a,[a])]
fun a (x:xs) 0 = []
fun a (x:xs) n = (a,x:xs):(fun a (xs++[x]) (n-1))
unicos :: Eq a => [a] -> [a]
unicos [] = []
unicos (x:xs) = x:(unicos(filter (x/=) xs))
[Ej. 8] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
10 de 20
....................................
noDups :: [Int] -> Bool
noDups [] = True
noDups (x:xs) = (foldr (&&) True ((map (x/=) xs))) && noDups xs
sublist :: [Int] -> [Int] -> Bool
sublist [] ys = True
sublist (x:xs) ys = (foldr (||) False ((map (x==) ys))) && sublist xs ys
removeDups :: [Int] -> [Int]
removeDups [] = []
removeDups (x:xs) = x:(removeDups(filter (x/=) xs))
f :: Int -> Int
f x = x*x
-- map f (removeDups xs) = removeDups (map f xs)
[Ej. 9] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
....................................
dropTrailingZeroes :: [Int] -> [Int]
dropTrailingZeroes = reverse . dropWhile (==0) . reverse
drop’ :: [Int] -> [Int]
11
drop’ [] = []
drop’ [0] = []
drop’ (x:xs) = x : drop’ (drop’ xs)
[Ej. 10] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
splitAt :: Int -> [a] -> ([a],[a])
splitAt n xs = (take n xs, drop n xs)
splitAt’ :: Int -> [a] -> ([a],[a])
splitAt’ _ [] = ([],[])
splitAt’ 0 xs = ([], xs)
splitAt’ n (x:xs) = (x:ns,ms) where (ns,ms) = splitAt’ (n-1) xs
sAt :: Int -> [a] -> ([a],[a])
sAt n xs = fst (foldr f (([],[]),length xs) xs)
where f x ((as,bs),m) = if (m > n) then ((as,x:bs),m-1) else ((x:as,bs),m)
[Ej. 11] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
filter :: (a -> Bool) -> [a] -> [a]
filter f xs = concat(map (\x -> if map f x == [True] then x else []) (map (:[]) xs))
{Como concat :: [[a]] -> [a] separo los elementos de la lista
en sublistas de 1 elemento.
Despues, me fijo en cada sublista si se cumple f
\x -> if map f x == [True] then x else []
transformando cada sublista donde no se cumple a la sublista [].
Finalmente se concatenan todas las sublistas devolviendo una lista.
Por ej:
filter (>0) [1,-2,3]
= concat [[1],[],[3]]
= [1,3]
-}
[Ej. 12] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
import List
tails :: [a] -> [[a]]
tails = map reverse . inits . reverse
tails’ :: [a] -> [[a]]
tails’ [] = [[]]
tails’ (x:xs) = (tails’ xs) ++ [(x:xs)]
[Ej. 13] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
inits :: [a] -> [[a]]
inits [] = [[]]
inits xs = inits( reverse(tail(reverse xs)) ) ++ [xs]
12
inits’ :: [a] -> [[a]]
inits’ xs = foldr (fun) [[]] (reverse xs) where fun x y = y ++ [(head (reverse y)) ++ [x]]
tails :: [a] -> [[a]]
tails [] = [[]]
tails (x:xs) = (tails xs) ++ [(x:xs)]
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
11 de 20
tails’ :: [a] -> [[a]]
tails’ xs = foldr (fun) [[]] xs where fun x y = y ++ [[x] ++ (head (reverse y))]
map :: (a -> b) -> [a] -> [b]
map f = foldr fun [] where fun x xs = f x : xs
[Ej. 14] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................
Teorema de Fusion para foldr.
Si f es estricta, con
f a = b (1)
y para todo x e y se tiene que
f (g x y) = h x (f y) (2)
entonces
f . foldr g a = foldr h b (*)
Demostracion
-*- Caso base []
f . foldr g a []
= f (foldr g a [])
= f (a)
foldr h b []
=b
-- x (1)
= f (a)
-*- Suponemos que vale para xs
f . foldr g a xs = foldr h b xs
-*- Probamos para (x:xs)
f . foldr g a (x:xs)
= f (foldr g a (x:xs))
= f (g x (foldr g a xs))
-- x (2)
= h x (f (foldr g a xs))
-- x h.i.
13
= h x (foldr h b xs)
= foldr h b (x:xs)
.: f . foldr g a (x:xs) = foldr h b (x:xs)
.: f . foldr g a = foldr h b (*)
Taller 3
Practica 3
1. Inferir, de ser posible, los tipos de las siguientes funciones:
a) modulus = sqrt · sum · map square;
b)
vmod[] = []
vmod(v:vs) = modulus v : vmod vs
c)
smap 0 f = map f
smap (n+1) f = map (smap n f)
2. Dar el tipo de las funciones que se definen a continuación:
a) hd (x:xs) = x;
b) tl (x:xs) = xs;
c) pred (x+1) = x;
3. ¿A qué valor reducen las siguientes expresiones, suponiendo evaluaciones lazy?
a) pred 0;
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
12 de 20
b) tl [pred 0];
c) hd (tl [pred 0]);
4. Definir un tipo de Colores y una función mezclar que permita la combinación de los
mismos.
5.
a) Definir las operaciones de suma y producto módulo 2 para el tipo
data DigBin = Cero |Uno
b) Definir las operaciones de suma binaria, producto por dos, cociente y resto de
la división por dos para el tipo:
type NumBin = [Digbin]
Donde convenimos que el primer elemento de las lista de dígitos es el digito
menos significativo del número representado.
c) Redefinir las funciones del ítem anterior, observando una convención opuesta.
d) Definir funciones que multipliquen números binarios de acuerdo a las dos
convenciones.
6. Un bag (o multiset) es una colecci´on de elementos. Cada elemento puede ocurrir un
o más
veces en el bag. Elija una representación eficiente para bags. Sería deseable que cada
bag tenga una representación ´única. Definir las siguientes operaciones sobre bags,
asegurándose de que aquellas que devuelvan bags lo hagan mediante una
representación valida.
a) list2bag, que toma una lista de elementos y devuelve un bag que contiene
esos elementos. El número de ocurrencia de un elemento en la lista y en el bag
resultante debe ser el mismo.
b) bagEmpty, que devuelve True exactamente cuando el bag dado está vacío.
c) bagCar, que devuelve su cardinalidad (cantidad total de ocurrencias de todos
los elementos).
d) bagElem, que devuelve verdadero si un elemento dado está en el bag dado;
e) bagOccur, que devuelve True si dos bags tienen los mismos elementos con la
misma cantidad de ocurrencias.
f) bagEqual, que devuelve True si dos bags tienen los mismos elementos con la
misma cantidad de ocurrencias.
g) bagSubbag, que devuelve True si el primer bag es subbag del segundo; se
dice que X es subbag de Y si cada elemento de X ocurre en Y al menos tantas
veces como en X.
h) bagInter, que toma dos bags y calcula el bag intersección. La intersección de
dos bags X e Y contiene a todos los elementos comunes a X e Y con la menos
cantidad posible de ocurrencias.
i) bagSum, que calcula el bag unión de dos bags dados; el bag suma de los dos
bags X e Y consiste de todos los elementos de X e Y con número de ocurrencias
de suma de las ocurrencias en cada uno de estos bags.
j) bagInsert, que toma un elemento y un bag y devuelve el bag con el elemento
insertado.
k) bagDelete, que toma un elemento y un bag, y devuelve el bag con el elemento
borrado.
7. Definir las operaciones de unión e intersección de dos conjuntos y el predicado de
pertenencia para conjuntos de elementos de tipo a representados.
a) por comprensión (como predicado a → Bool);
b) por extensión (como lista de elementos de a).
SOLUCIÒN:
Ej.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
..............................
modulus :: [Float] -> Float
modulus = sqrt.sum.map square
square :: Float -> Float
square x = x^2
vmod :: [[Float]] -> [Float]
vmod [] = []
vmod (v:vs) = modulus v : vmod vs
{smap 0 f = map f
smap (n+1) f = map (smap n f)
No se puede tipear la función smap en haskell por que su tipo depende de su
argumento, en este caso, de (n+1). El caso base de smap devuelve una funcion
g :: [a] -> [a]
Si n = 0 smap devuelve
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
13 de 20
g’ :: [[a]] -> [[a]]
Si n = 1 smap devuelve
g’’ :: [[[a]]] -> [[[a]]]
y asi sucesivamente.
-}
Ej. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
..............................
hd :: [a] -> a
hd (x:xs) = x
tl :: [a] -> [a]
tl (x:xs) = xs
pred :: Int -> Int
pred (x + 1) = x
Ej. 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
..............................
---> pred 0
Program error: pattern match failure: pred 0
Produce error porque no está definida la funcion
pred para un n tal que n+1 = 0
pred 0
= x falta de pattern matching
(no está definida para algún n tal que n+1=0)
bottom
---> tl [pred 0]
[]
Devuelve la lista vacía por que la lista que se
le pasa a tl es (x:xs) = (pred 0:[])
tl [pred 0]
= x notacion
tl (pred 0:[])
= x def de tl
[]
---> hd (tl [pred 0])
Program error: pattern match failure: hd []
hd(tl [pred 0])
= x notacion
hd(tl (pred 0:[])
= x def de tl
hd([])
= x falta de PM -> indefinido
bottom
Ej. 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
..............................
data Color = C Int Int Int
deriving Show
mezclar :: Color -> Color -> Color
mezclar (C r1 g1 b1) (C r2 g2 b2) =
C ((r1 + r2) ‘div‘ 2) ((g1 + g2) ‘div‘ 2) ((b1 + b2) ‘div‘ 2)
Ej. 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
..............................
data DigBin = Cero | Uno
deriving (Show, Eq)
{0+0=0
0+1=1
1+0=1
1 + 1 ,Acarreo 0 = 0, Acarreo 1
1 + 1 ,Acarreo 1 = 1, Acarreo 1
Por ej:
111 -> Acarreo
1010
1111
---11001
-}
-- Suma basica de binarios
suma :: DigBin -> DigBin -> DigBin
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
14 de 20
suma Cero Cero = Cero
suma Cero Uno = Uno
suma Uno Cero = Uno
suma Uno Uno = Cero
-- Producto Modulo 2
pmod2 :: DigBin -> DigBin -> DigBin
pmod2 Cero Cero = Cero
pmod2 Cero Uno = Cero
pmod2 Uno Cero = Cero
pmod2 Uno Uno = Uno
-- Esta funcion suma números binarios con el bit menos significativo como
-- el primer elemento de la lista
type NumBin = [DigBin]
sumab_rev :: NumBin -> NumBin -> NumBin
sumab_rev x y = suma’ x y Cero
-- Las demás no las defino xq no tengo ganas.
-- Ahora usando la convención standard, donde el primer elemento de la lista es el
-- bit mas significativo.
-- Como la suma es de derecha a izquierda primero doy vuelta el orden de la lista
-- si no empieza sumando del bit mas significativo al menos significativo y es al
-- revés. Antes de devolverla vuelvo a dar vuelta el resultado para que se pueda
-- leer como número binario.
sumab :: NumBin -> NumBin -> NumBin
sumab x y
| length x == length y = reverse (suma’ (reverse x) (reverse y) Cero)
| otherwise = error ("Los números binarios no tienen la misma cantidad de bits")
suma’ :: NumBin -> NumBin -> DigBin -> NumBin
suma’ [] [] acarreo
| acarreo == Cero = []
| acarreo == Uno = Uno:[]
suma’ [] (x:xs) acarreo = suma’ (x:xs) [] acarreo
suma’ (x:xs) [] acarreo
| x == Cero && acarreo == Cero = Cero :(suma’ xs [] Cero)
| x == Uno && acarreo == Cero = Uno :(suma’ xs [] Cero)
| x == Cero && acarreo == Uno = Cero :(suma’ xs [] Uno)
| x == Uno && acarreo == Uno = Cero :(suma’ xs [] Uno)
suma’ (x:xs) (y:ys) acarreo
| x == Cero && y == Cero && acarreo == Cero = Cero :(suma’ xs ys Cero)
| x == Cero && y == Uno && acarreo == Cero = Uno :(suma’ xs ys Cero)
| x == Uno && y == Cero && acarreo == Cero = Uno :(suma’ xs ys Cero)
| x == Cero && y == Cero && acarreo == Uno = Uno :(suma’ xs ys Cero)
| x == Cero && y == Uno && acarreo == Uno = Cero :(suma’ xs ys Uno)
| x == Uno && y == Cero && acarreo == Uno = Cero :(suma’ xs ys Uno)
| x == Uno && y == Uno && acarreo == Cero = Cero :(suma’ xs ys Uno)
| x == Uno && y == Uno && acarreo == Uno = Uno :(suma’ xs ys Uno)
prodx2 :: NumBin -> NumBin
prodx2 x = sumab x x
{Vamos a usar la resta, sumando el complemento a 2:
El complemento a 1 de un valor binario se obtiene invirtiendo el estado
de todas sus cifras, incluyendo los ceros a la izquierda hasta completar
la capacidad del registro. Por ejemplo, el valor 10011 en un registro de
8 bits (cifras) sería 00010011 y su complemento a 1 sería 11101100.
El complemento a 2 de un valor binario se obtiene sumando 1 al complemento
a 1. Por ejemplo, el complemento a 2 de 10011 (el mismo anterior) sería
11101100 + 1 = 11101101.
Como restar sumando: El complemento a 2 de un número binario se puede
considerar directamente su equivalente negativo. Por lo tanto, para hacer
la resta a - b = ¿x? basta con calcular el resultado "x" (sin olvidar el
tamaño del registro que se utilice) como:
x = a + (complemento a 2 de b)
Utilizando el Complemento a dos. La resta de dos n´umeros binarios puede
obtenerse sumando al minuendo el complemento a dos del sustraendo. Veamos
algunos ejemplos: Hagamos la siguiente resta, 91 - 46 = 45, en binario:
1011011 1011011
-0101110 C246 = 1010010 +1010010
-------- -------0101101 10101101
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
15 de 20
En el resultado nos sobra un bit, que se desborda por la izquierda.
Pero, como el n´umero resultante no puede ser más largo que el minuendo,
el bit sobrante se desprecia.
-}
complemento_1 :: NumBin -> NumBin
complemento_1 [] = []
complemento_1 (x:xs)
| x == Cero = Uno : complemento_1 xs
| x == Uno = Cero : complemento_1 xs
complemento_2 :: NumBin -> NumBin
complemento_2 x = sumab (complemento_1 x) (binUnoConZeros (length x))
-- Esta funcion genera el numero binario uno de n bits [Cero,Cero,...,Uno]
-- para poder hacer el complemento a 2
binUnoConZeros :: Int -> NumBin
binUnoConZeros 1 = [Uno]
binUnoConZeros n = Cero : binUnoConZeros (n-1)
restab :: NumBin -> NumBin -> NumBin
restab x y
| length(sumab x (complemento_2 y)) > length x = tail(sumab x (complemento_2 y))
| otherwise = sumab x (complemento_2 y)
-- La división x 2 es un shift a la derecha, descartando el último bit
-- 1010 / 2 = 0101
cocientebx2 :: NumBin -> NumBin
cocientebx2 x = Cero : reverse(tail(reverse x))
-- El resto de la división x 2 es el bit que desaparecería si hiciésemos
-- un shift a la derecha
restococientebx2 :: NumBin -> DigBin
restococientebx2 x = head(reverse x)
Ej. 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
..............................
-- Defino los Bags como una lista de tuplas
-- [(elemento, Numero de apariciones de un elemento)]
type Bag a = [(a,Int)]
--list2bag :: [a] -> Bag a
list2bag [] = []
list2bag (x:xs) = bagInsert x (list2bag xs)
--bagInsert :: a -> Bag a -> Bag a
bagInsert a [] = [(a,1)]
bagInsert a ((b,n):xs) = if a == b then (b,n+1):xs
else (b,n):bagInsert a xs
bagEmpty x = if x == [] then True else False
bagCar [] = 0
bagCar ((b,n):xs) = n + bagCar xs
bagElem a [] = False
bagElem a ((b,n):xs) = if a == b then True else bagElem a xs
bagOcurr a [] = False
bagOcurr (a,n) ((b,m):xs) = if a == b && n==m then True else bagOcurr (a,n) xs
bagEqual [] [] = True
bagEqual _ [] = False
bagEqual [] _ = False
bagEqual ((a,n):xs) ((b,m):ys) = if a==b && n==m
then True && bagEqual xs ys
else False
bagSubbag [] [] = True
bagSubbag _ [] = False
bagSubbag [] _ = True
bagSubbag ((a,n):xs) ((b,m):ys) = if a==b && n<=m
then True && bagSubbag xs ys
else bagSubbag ((a,n):xs) ys
bagminEnbag [] [] = 0
bagminEnbag _ [] = 0
bagminEnbag [] _ = 0
bagminEnbag [(a,n)] ((b,m):ys) = if a==b
then min n m
else bagminEnbag [(a,n)] ys
bagInter [] _ = []
bagInter ((a,n):xs) ((b,m):ys) = if x > 0
then (a, x):bagInter xs ((b,m):ys)
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
16 de 20
else bagInter xs ((b,m):ys)
where x = bagminEnbag [(a,n)] ((b,m):ys)
insertNveces a 1 ys = bagInsert a ys
insertNveces a n ys = bagInsert a (insertNveces a (n-1) ys)
bagSum [] ys = ys
bagSum ((a,n):xs) ys = bagSum xs (insertNveces a n ys)
bagDelete _ [] = []
bagDelete (a,n) ((b,m):ys)
| a/=b = (b,m):bagDelete (a,n) ys
| a==b && n>=m = ys
| a==b && n<m = (b,m-n):ys
TALLER 2
1. Sin usar funciones de alto orden ni funciones definidas en el preludio, defina recursivamente
las siguientes funciones y determine su tipo más general:
a) suma, que suma todos los elementos de una lista de números
b) alguno, que devuelve True si algún elemento de una lista de valores booleanos es True, y
False en caso contrario
c) todos, que devuelve True si todos los elementos de una lista de valores booleanos son
True y False en caso contrario
d ) codes, que dada una lista de caracteres, devuelve la lista de sus ordinales
e) restos, que calcula la lista de los restos de la división de los elementos de una lista de
números dada por otro número dado
f) cuadrados, que dada una lista de números, devuelva la lista de sus cuadrados
g) longitudes, que dada una lista de listas, devuelve la lista de sus longitudes
h) orden, que dada una lista de pares de números, devuelve la lista de aquellos pares en los
que la primera componente es menor que el triple de la segunda
i ) pares, que dada una lista de enteros, devuelve la lista de los elementos pares
j) letras, que dada una lista de caracteres, devuelve la lista de aquellos que son letras
(minúsculas o mayúsculas)
k) masDe, que dada una lista de listas xss y un número n, devuelve la lista de aquellas listas
de xss con longitud mayor que n
2. Indicar bajo que suposiciones pueden evaluarse las siguientes ecuaciones. Para aquellas que
puedan evaluarse indicar si son verdaderas y en caso de no serlo modificar su lado derecho para
que resulten verdaderas:
a) [[]] ++ xs = xs
b) [[]] ++ xs = [xs]
c) [[]] ++ xs = [] : xs
d) [[]] ++ xs = [[],xs]
e) [[]] ++ [xs] = [[],xs]
f) [[]] ++ [xs] = [xs]
g) [] ++ xs = [] : xs
h) [] ++ xs = xs
i) [xs] ++ [] = [xs]
j) [xs] ++ [xs] = [xs,xs]
k) [] : xs = xs
3. Demostrar la siguiente propiedad: sum xs ≤ length xs ∗ maxl xs, sabiendo que xs es una
lista de números naturales y que
maxl [] = 0 sum [] = 0
maxl (x:xs) = x ‘max‘ maxl xs sum (x:xs) = x + sum xs
4. Defina una función all :: (c → Bool) →[a] → Bool tal que all p xs = True exclusivamente
en el caso que todos los elementos de xs satisfagan el predicado p.
5. Defina las siguientes funciones:
a) isPrime :: Int →Bool, que decide si un número positivo es o no primo.
b) primes :: Int →[Int], tal que primes n es la lista de los números primos menores o
iguales que n para n > 0.
c) product :: [Int] →Int, tal que product xs es el producto de todos los elementos de xs.
N.B: Recuerde que un producto con ningún factor vale 1.
d) factors :: Int →[Int] tal que
• all isPrime (factors x) = True
• product · factors = id
para cada entero positivo x.
6. Demostrar las siguientes propiedades:
a) curry · uncurry = id
b) uncurry · curry = id
7. Se puede definir la sintaxis de un lenguaje sencillo en forma inductiva de la siguiente manera:
El conjunto de términos es el menor conjunto τ tal que:
1. {true, false, 0} ⊆ τ ;
2. if t1 ∈ τ , then {succ t1, pred t1, iszero t1} ⊆ τ ;
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
17 de 20
3. if t1 ∈ τ , t2 ∈ τ , t3 ∈ τ , then if t1 then t2 else t3 ∈ τ .
Otra forma de definir el mismo conjunto de t´erminos es un estilo más ”‘concreto”’ que
proporciona una manera explicita de generar los elementos de τ :
Para cada natural i, se define un conjunto Si como sigue:
S0 =
Si+1 = {true, false, 0}
∪ {succ t1, pred t1, iszero t1 | t1 ∈ Si}
∪ {if t1 then t2 else t3 | t1, t2, t3 ∈ Si}
Finalmente: S =
S
i Si
.
a) ¿Cuál es la cantidad de elementos de S3?.
b) Mostrar que los conjuntos Si son acumulativos, es decir, que para cada i tenemos Si ⊆ Si+1.
Practica 2 2006 Pagina 2
Análisis de Lenguajes de Programación II
c) Demostrar que τ = S.
d) ¿Es posible generalizar este ´ultimo estilo de definición para cualquier definición inductiva?
8.
a) Sean xs = [1,2,3], ys = [4,5,6] y zs = [7,8,9], reduzca las siguientes expresiones
usando la definición recursiva de ++ :
• xs ++ (ys ++ zs);
• (xs ++ ys) ++ zs;
b) ¿Cuál de las dos expresiones se evalúa en menos pasos?
c) ¿El operador ++ debería asociar a izquierda o a derecha?
d) ¿Que asociatividad se declara para ++ en el preludio de Haskell?
Solución Taller 2
suma :: [Int] -> Int
suma [] = 0
suma (x:xs) = x + suma xs
suma’ :: [Int] -> Int
suma’ = foldr (+) 0
alguno :: [Bool] -> Bool
alguno [] = False
alguno (x:xs) = x || alguno xs
alguno’ :: [Bool] -> Bool
alguno’ = foldr (||) False
todos :: [Bool] -> Bool
todos [] = True
todos (x:xs) = x && todos xs
todos’ :: [Bool] -> Bool
todos’ = foldr (&&) True
codes :: [Char] -> [Int]
codes [] = []
codes (x:xs) = ord(x):codes xs
codes’ :: [Char] -> [Int]
codes’ = map ord
restos :: Int -> [Int] -> [Int]
restos n [] = []
restos n (x:xs) = (x ‘mod‘ n):restos n xs
restos’ :: Int -> [Int] -> [Int]
restos’ = \n -> map (‘mod‘ n)
cuadrados :: [Int] -> [Int]
cuadrados [] = []
cuadrados (x:xs) = (x*x):cuadrados xs
cuadrados’ :: [Int] -> [Int]
cuadrados’ = map (\x -> x*x)
longitudes :: [[a]] -> [Int]
longitudes [] = []
longitudes (xs:xss) = length(xs):longitudes xss
longitudes’ :: [[a]] -> [Int]
longitudes’ = map (length)
orden :: [(Int,Int)] -> [(Int,Int)]
1
orden [] = []
orden (x:xs) = if fst(x) > snd(x) then x : orden xs else orden xs
orden’ :: [(Int,Int)] -> [(Int,Int)]
orden’ = filter (\x -> (fst(x) > snd(x)))
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
18 de 20
pares :: [Int] -> [Int]
pares [] = []
pares (x:xs) = if mod x 2 == 0 then x:pares xs else pares xs
pares’ :: [Int] -> [Int]
pares’ = filter (\x -> x ‘mod‘ 2 == 0)
masDe :: Int -> [[a]] -> [[a]]
masDe n [] = []
masDe n (xs:xss) = if length(xs) > n then xs : masDe n xss else masDe n xss
masDe’ :: Int -> [[a]] -> [[a]]
masDe’ = \n -> filter (\x -> length x > n)
[Ej. 2] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
......................
a) Si xs = [[a]] -Falso - [[]] ++ xs = [[],xs]
b) Si xs = [[a]] -Falso - [[]] ++ xs = [[],xs]
c) Si xs = [[a]] -False - [[]] ++ xs = [[],xs]
d) Si xs = [[a]] -Verdadero
e) Si xs = [a] - Verdadero
f) Si xs = [a] - Falso -[[]] ++ xs = [[],xs]
g) Si xs = [a] - Falso - [] ++ xs = xs
h) Si xs = [a] - Verdadero
i) Si xs = a - Verdadero
j) Para todo xs -Verdadero
k) Si xs = [[a]] - Verdadero - [] : xs = xs
[Ej. 3] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
......................
(1) -> maxl [] = 0
(2) -> maxl (x:xs) = x ‘max‘ maxl xs
(3) -> sum [] = 0
(4) -> sum (x:xs) = x + sum xs
Vamos a demostrar que
sum xs <= length xs * maxl xs
=
x_1 + sum x_2 + ... + sum x_n <= n * max { x_1, ..., x_n }
=
[Ej. 4] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
......................
-- Esta funcion hace lo que pide el enunciado
-- no se puede hacer si el tipo es
-- (c -> Bool) -> [a] -> Bool
-- por que la funcion que toma como argumento
2
-- tiene que ser si o si (a -> Bool) para examinar
-- los elementos de la lista y devolver algo
-- En este caso usamos la funcion positivo
-- para que siempre se satisfaga el predicado p
all’ :: (a -> Bool) -> [a] -> Bool
all’ p [] = True
all’ p (x:xs) = (p x) && (all’ p xs)
-- Esta funcion es de tipo
-- (c -> Bool) -> [a] -> Bool
-- pero no hace lo que pide el enunciado
all’’ :: (c -> Bool) -> [a] -> Bool
all’’ p (x:xs) = True
positivo :: c -> Bool
positivo c = True
[Ej. 5] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
......................
isPrime :: Int -> Bool
isPrime x = primeDiv x (x-1)
primeDiv :: Int -> Int -> Bool
primeDiv 1 0 = True
primeDiv x 1 = True
primeDiv x y = ((x ‘mod‘ y) > 0) && (primeDiv x (y-1) )
-- isPrime2 es mucho mas eficiente que isPrime
-- para descartar numeros que no son primos
isPrime2 :: Int -> Bool
isPrime2 x = primeDiv2 x 2
primeDiv2:: Int -> Int -> Bool
primeDiv2 x y
| x == 1 = True
| x == y = True
| ((x ‘mod‘ y) == 0) = False
| otherwise = (True && primeDiv2 x (y+1))
-- Se comprueba buscando los primeros n primos
primes :: Int -> [Int]
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
19 de 20
primes x = listPrimos isPrime x 0 []
primes2 :: Int -> [Int]
primes2 x = listPrimos isPrime2 x 0 []
listPrimos :: (Int -> Bool) -> Int -> Int -> [Int] -> [Int]
listPrimos f a b c
| a == b = if f b == True then c++[b] else c
| otherwise = if f b == True
then listPrimos f a (b+1) c++[b]
3
else listPrimos f a (b+1) c
-- no se puede usar el nombre "product"
produc :: [Int] -> Int
produc = foldr (*) 1
factors :: Int -> [Int]
factors x = buscarFactors x 2 [1]
buscarFactors :: Int -> Int -> [Int] -> [Int]
buscarFactors a b c
| a == 1 = [1]
| a == b = if (isPrime2 b) == True then c ++ [b] else c
| otherwise = if ((a ‘mod‘ b) == 0) && (isPrime2 b) == True
then buscarFactors (div a b) 2 c ++ [b]
else buscarFactors a (b+1) c
[Ej. 8] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
......................
(0) - jj :: [a] -> [a] -> [a]
(1) - [] ‘jj‘ ys = ys
(2) - (x:xs) ‘jj‘ ys = x : (xs ‘jj‘ ys)
xs = [1,2,3]
ys = [4,5,6]
zs = [7,8,9]
[1,2,3] ++ ([4,5,6] ++ [7,8,9])
= x notacion
(1:(2:(3:[]))) ++ ((4:(5:(6:[]))) ++ (7:(8:(9:[]))))
= x def ++ 2
1:(2:(3:[]))) ++ (4:((5:(6:[]))) ++ (7:(8:(9:[]))))
= x def ++ 2
1:(2:(3:[]))) ++ (4:(5:(6:([] ++ (7:(8:(9:[])))))))
= x def ++ 1
1:(2:(3:[]))) ++ (4:(5:(6:(7:(8:(9:[]))))))
= x def ++ 2
1:(2:(3:([] ++ (4:(5:(6:(7:(8:(9:[])))))))))
= x def ++ 1
1:(2:(3:(4:(5:(6:(7:(8:(9:[]))))))))
= x notacion
[1,2,3,4,5,6,7,8,9]
([1,2,3] ++ [4,5,6]) ++ [7,8,9]
= x notacion
((1:(2:(3:[]))) ++ (4:(5:(6:[])))) ++ (7:(8:(9:[])))
= x def ++ 2
(1:(2:(3:[] ++ (4:((5:(6:[]))))))) ++ (7:(8:(9:[])))
= x def ++ 2
(1:(2:(3:([] ++ (4:(5:(6:[]))))))) ++ (7:(8:(9:[])))
Publicado por Diego Moreno - Consultor Tecnologico en 19:13
No hay comentarios:
Publicar un comentario
Enter your comment...
Comment as:
Publicar
Liceo Libertad inscripciones Plan 94 (Go
Sign out
Notify me
Vista previa
Inicio
1/10/2021 8:40
APRENDIENDO HASKELL-EJERCICIOS: Aprendiendo Haskell- Ejerc... http://aprendiendohaskell.blogspot.com/2016/05/aprendiendo-haskell-eje...
20 de 20
Suscribirse a: Enviar comentarios (Atom)
Tema Sencillo. Con la tecnología de Blogger.
1/10/2021 8:40
Descargar