-- | -- Module : Alfabeto_desde -- Description : Alfabeto comenzando en un carácter. -- Copyright : Exercitium (12-05-14) -- License : GPL-3 -- Maintainer : JoseA.Alonso@gmail.com -- -- Definir la función -- -- > alfabetoDesde :: Char -> String -- -- tal que __(alfabetoDesde c)__ es el alfabeto, en minúscula, comenzando en -- el carácter c, si c es una letra minúscula y comenzando en 'a', en -- caso contrario. Por ejemplo, -- -- >>> alfabetoDesde 'e' -- "efghijklmnopqrstuvwxyzabcd" -- >>> alfabetoDesde 'a' -- "abcdefghijklmnopqrstuvwxyz" -- >>> alfabetoDesde '7' -- "abcdefghijklmnopqrstuvwxyz" -- >>> alfabetoDesde '{' -- "abcdefghijklmnopqrstuvwxyz" -- >>> alfabetoDesde 'B' -- "abcdefghijklmnopqrstuvwxyz" module Alfabeto_desde where import Data.Char (isAsciiLower) import Data.Tuple (swap) import Test.QuickCheck -- | 1ª definición (con 'dropWhile' y 'takeWhile'). alfabetoDesde :: Char -> String alfabetoDesde c = dropWhile (<c) ['a'..'z'] ++ takeWhile (<c) ['a'..'z'] -- | 2ª definición (con 'span'). alfabetoDesde2 :: Char -> String alfabetoDesde2 c = ys ++ xs where (xs,ys) = span (<c) ['a'..'z'] -- | 3ª definición (con 'break'). alfabetoDesde3 :: Char -> String alfabetoDesde3 c = ys ++ xs where (xs,ys) = break (==c) ['a'..'z'] -- | 4ª definición (sin argumentos): alfabetoDesde4 :: Char -> String alfabetoDesde4 = uncurry (++) . swap . flip span ['a'..'z'] . (>) -- Ejemplo de cálculo: -- alfabetoDesde4 'e' -- = (uncurry (++) . swap . flip span ['a'..'z'] . (>)) 'e' -- = (uncurry (++) . swap) ("abcd","efghijklmnopqrstuvwxyz") -- = uncurry (++) ("efghijklmnopqrstuvwxyz","abcd") -- = (++) "efghijklmnopqrstuvwxyz" "abcd" -- = "efghijklmnopqrstuvwxyzabcd" -- | 5ª definición (sin argumentos). alfabetoDesde5 :: Char -> String alfabetoDesde5 = uncurry (flip (++)) . (`break` ['a'..'z']) . (==) -- Ejemplo de cálculo: -- alfabetoDesde5 'e' -- = (uncurry (flip (++)) . (`break` ['a'..'z']) . (==)) 'e' -- = uncurry (flip (++)) ("abcd","efghijklmnopqrstuvwxyz") -- = flip (++) "abcd" "efghijklmnopqrstuvwxyz" -- = "efghijklmnopqrstuvwxyz" ++ "abcd" -- = "efghijklmnopqrstuvwxyzabcd" -- | 6ª definición (por comprensión). alfabetoDesde6 :: Char -> String alfabetoDesde6 c | c >= 'a' && c <= 'z' = [c..'z'] ++ ['a'..pred c] | otherwise = ['a'..'z'] -- | 7ª definición (por comprensión con 'isAsciiLower'). alfabetoDesde7 :: Char -> String alfabetoDesde7 c | isAsciiLower c = [c..'z'] ++ ['a'..pred c] | otherwise = ['a'..'z'] -- | (prop_alfabetoDesde c) se verifica si las definiciones de -- alfabetoDesde sobre c. Por ejemplo, -- -- >>> :{ -- and [ prop_alfabetoDesde 'e' -- , prop_alfabetoDesde 'a' -- , prop_alfabetoDesde '7' -- , prop_alfabetoDesde '{' -- , prop_alfabetoDesde 'B' -- ] -- :} -- True prop_alfabetoDesde :: Char -> Bool prop_alfabetoDesde c = all (== alfabetoDesde c) [f c | f <- [ alfabetoDesde2 , alfabetoDesde3 , alfabetoDesde4 , alfabetoDesde5 , alfabetoDesde6 , alfabetoDesde7 ]] -- | Comprueba la equivalencia de las definiciones. -- -- >>> verifica_alfabetoDesde -- +++ OK, passed 100 tests. verifica_alfabetoDesde :: IO () verifica_alfabetoDesde = quickCheck prop_alfabetoDesde