Siguiente elemento en una lista
Definir la función
1 |
siguiente :: Eq a => a -> [a] -> Maybe a |
tal que (siguiente x ys) es justo el elemento siguiente a la primera ocurrencia de x en ys o Nothing si x no pertenece a ys. Por ejemplo,
1 2 3 4 5 6 7 |
siguiente 5 [3,5,2,5,7] == Just 2 siguiente 9 [3,5,2,5,7] == Nothing siguiente 'd' "afdegdb" == Just 'e' siguiente "todo" ["En","todo","la","medida"] == Just "la" siguiente "nada" ["En","todo","la","medida"] == Nothing siguiente 999999 [1..1000000] == Just 1000000 siguiente 1000000 [1..1000000] == Nothing |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import Data.Maybe (listToMaybe) -- Para la 4ª solución -- 1ª solución (por recursión): siguiente1 :: Eq a => a -> [a] -> Maybe a siguiente1 x (y1:y2:ys) | x == y1 = Just y2 | otherwise = siguiente1 x (y2:ys) siguiente1 x _ = Nothing -- 2ª solución (por comprensión): siguiente2 :: Eq a => a -> [a] -> Maybe a siguiente2 x ys | null zs = Nothing | otherwise = Just (snd (head zs)) where zs = [(u,v) | (u,v) <- zip ys (tail ys), u == x] -- 3ª solución (con dropWhile) siguiente3 :: Eq a => a -> [a] -> Maybe a siguiente3 x = aux . drop 1 . dropWhile (/=x) where aux [] = Nothing aux (y:_) = Just y -- 4ª solución (con dropWhile y listToMaybe): siguiente4 :: Eq a => a -> [a] -> Maybe a siguiente4 x = listToMaybe . drop 1 . dropWhile (/=x) -- Nota: En la librería Data.Maybe está definida la función -- listToMaybe :: [a] -> Maybe a -- tal que (listToMaybe xs) es Nothing si la lista xs está vacía y es -- justo el primer elemento, en caso contrario, Por ejemplo, -- listToMaybe [] == Nothing -- listToMaybe [3,2,5] == Just 3 -- Comparación de eficiencia -- ========================= -- La comparación es -- ghci> let n=10^6 in siguiente1 (n-1) [1..n] -- Just 1000000 -- (1.34 secs, 277352616 bytes) -- -- ghci> let n=10^6 in siguiente2 (n-1) [1..n] -- Just 1000000 -- (1.45 secs, 340836576 bytes) -- -- ghci> let n=10^6 in siguiente3 (n-1) [1..n] -- Just 1000000 -- (0.26 secs, 84987544 bytes) -- -- ghci> let n=10^6 in siguiente4 (n-1) [1..n] -- Just 1000000 -- (0.26 secs, 84987440 bytes) |
Aprovechando que Maybe es una mónada
Usando monad comprehension
La definición es semánticamente equivalente a la primera salvo que no tiene la guarda (return == Just para Maybe). El no tener la guarda provoca que para el caso
La desugarización de la notación con do de la versión monádica (con guarda) sería