Repetición de elementos
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
λ> 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 -- λ> 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 -- λ> quickCheckWith (stdArgs {maxSize=7}) prop_repiteElementos -- +++ OK, passed 100 tests.