Enunciado
-- Definir la función
-- repiteElementos :: Int -> [a] -> [a]
-- tal que (repiteElementos k xs) es la lista obtenida repitiendo cada
-- elemento de xs k veces. Por ejemplo,
-- repiteElementos 3 [5,2,7,4] == [5,5,5,2,2,2,7,7,7,4,4,4]
--
-- Comprobar con QuickCheck que, para todo número natural k y toda lista
-- xs, el número de elementos de (repiteElementos k xs) es k veces el
-- número de elementos de xs.
--
-- Nota. Al hacer la comprobación limitar el tamaño de las pruebas como
-- se indica a continuación
-- ghci> quickCheckWith (stdArgs {maxSize=7}) prop_repiteElementos
-- +++ OK, passed 100 tests. |
-- Definir la función
-- repiteElementos :: Int -> [a] -> [a]
-- tal que (repiteElementos k xs) es la lista obtenida repitiendo cada
-- elemento de xs k veces. Por ejemplo,
-- repiteElementos 3 [5,2,7,4] == [5,5,5,2,2,2,7,7,7,4,4,4]
--
-- Comprobar con QuickCheck que, para todo número natural k y toda lista
-- xs, el número de elementos de (repiteElementos k xs) es k veces el
-- número de elementos de xs.
--
-- Nota. Al hacer la comprobación limitar el tamaño de las pruebas como
-- se indica a continuación
-- ghci> quickCheckWith (stdArgs {maxSize=7}) prop_repiteElementos
-- +++ OK, passed 100 tests.
Soluciones
import Test.QuickCheck
-- 1ª definición (por comprensión):
repiteElementos1 :: Int -> [a] -> [a]
repiteElementos1 k xs = concat [replicate k x | x <- xs]
-- 2ª definición (con map)
repiteElementos2 :: Int -> [a] -> [a]
repiteElementos2 k xs = concat (map (replicate k) xs)
-- 3ª definición (con concatMap):
repiteElementos3 :: Int -> [a] -> [a]
repiteElementos3 k = concatMap (replicate k)
-- 4ª definición (por recursión):
repiteElementos4 :: Int -> [a] -> [a]
repiteElementos4 k [] = []
repiteElementos4 k (x:xs) = replicate k x ++ repiteElementos4 k xs
-- 5ª definición (por plegado):
repiteElementos5 :: Int -> [a] -> [a]
repiteElementos5 k = foldr ((++) . replicate k) []
-- Propiedad de equivalencia
prop_equivalencia :: Int -> [Int] -> Bool
prop_equivalencia k xs =
repiteElementos2 k xs == ys &&
repiteElementos3 k xs == ys &&
repiteElementos4 k xs == ys &&
repiteElementos5 k xs == ys
where ys = repiteElementos1 k xs
-- Su comprobación es
-- ghci> quickCheckWith (stdArgs {maxSize=10}) prop_equivalencia
-- +++ OK, passed 100 tests.
-- La propiedad es
prop_repiteElementos :: Int -> [Int] -> Property
prop_repiteElementos k xs =
k >= 0 ==> length (repiteElementos1 k xs) == k * length xs
-- La comprobación es
-- ghci> quickCheckWith (stdArgs {maxSize=7}) prop_repiteElementos
-- +++ OK, passed 100 tests. |
import Test.QuickCheck
-- 1ª definición (por comprensión):
repiteElementos1 :: Int -> [a] -> [a]
repiteElementos1 k xs = concat [replicate k x | x <- xs]
-- 2ª definición (con map)
repiteElementos2 :: Int -> [a] -> [a]
repiteElementos2 k xs = concat (map (replicate k) xs)
-- 3ª definición (con concatMap):
repiteElementos3 :: Int -> [a] -> [a]
repiteElementos3 k = concatMap (replicate k)
-- 4ª definición (por recursión):
repiteElementos4 :: Int -> [a] -> [a]
repiteElementos4 k [] = []
repiteElementos4 k (x:xs) = replicate k x ++ repiteElementos4 k xs
-- 5ª definición (por plegado):
repiteElementos5 :: Int -> [a] -> [a]
repiteElementos5 k = foldr ((++) . replicate k) []
-- Propiedad de equivalencia
prop_equivalencia :: Int -> [Int] -> Bool
prop_equivalencia k xs =
repiteElementos2 k xs == ys &&
repiteElementos3 k xs == ys &&
repiteElementos4 k xs == ys &&
repiteElementos5 k xs == ys
where ys = repiteElementos1 k xs
-- Su comprobación es
-- ghci> quickCheckWith (stdArgs {maxSize=10}) prop_equivalencia
-- +++ OK, passed 100 tests.
-- La propiedad es
prop_repiteElementos :: Int -> [Int] -> Property
prop_repiteElementos k xs =
k >= 0 ==> length (repiteElementos1 k xs) == k * length xs
-- La comprobación es
-- ghci> quickCheckWith (stdArgs {maxSize=7}) prop_repiteElementos
-- +++ OK, passed 100 tests.
Se puede imprimir o compartir con
Usando concatMap para simplificar:
se pueden suprimir las xs y seguiría funcionando.