Definir la función
siguiente :: Eq a => a -> [a] -> Maybe a |
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,
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 |
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
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) |
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)
Se puede imprimir o compartir con
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