repetidos multiplos multiplicar listas lista infinitas elementos ejercicios contador ciclos basico list haskell

multiplos - elementos únicos en una lista de haskell



multiplicar haskell (6)

Busqué (Eq a) => [a] -> [a] en Hoogle .

El primer resultado fue nub (eliminar elementos duplicados de una lista).

Hoogle es increíble.

bien, esto probablemente estará en el preludio, pero ¿hay una función de biblioteca estándar para encontrar los elementos únicos en una lista? mi (re) implementación, para aclarar, es:

has :: (Eq a) => [a] -> a -> Bool has [] _ = False has (x:xs) a | x == a = True | otherwise = has xs a unique :: (Eq a) => [a] -> [a] unique [] = [] unique (x:xs) | has xs x = unique xs | otherwise = x : unique xs


Creo que eso único debería devolver una lista de elementos que solo aparecen una vez en la lista original; es decir, cualquier elemento de la lista original que aparezca más de una vez no debe incluirse en el resultado.

Puedo sugerir una definición alternativa, unique_alt:

unique_alt :: [Int] -> [Int] unique_alt [] = [] unique_alt (x:xs) | elem x ( unique_alt xs ) = [ y | y <- ( unique_alt xs ), y /= x ] | otherwise = x : ( unique_alt xs )

Aquí hay algunos ejemplos que resaltan las diferencias entre unique_alt y unqiue:

unique [1,2,1] = [2,1] unique_alt [1,2,1] = [2] unique [1,2,1,2] = [1,2] unique_alt [1,2,1,2] = [] unique [4,2,1,3,2,3] = [4,1,2,3] unique_alt [4,2,1,3,2,3] = [4,1]


La función nub de Data.List (no, en realidad no está en el Preludio) definitivamente hace algo como lo que quieres, pero no es lo mismo que tu función unique . Ambos conservan el orden original de los elementos, pero el unique conserva la última ocurrencia de cada elemento, mientras que nub retiene la primera ocurrencia.

Puedes hacer esto para que nub actúe exactamente como unique , si eso es importante (aunque tengo la sensación de que no lo es):

unique = reverse . nub . reverse

Además, nub solo es bueno para listas pequeñas. Su complejidad es cuadrática, por lo que comienza a ser lenta si su lista puede contener cientos de elementos.

Si limita sus tipos a tipos que tienen una instancia Ord, puede hacer que escale mejor. Esta variación en nub aún conserva el orden de los elementos de la lista, pero su complejidad es O(n * log n) :

import qualified Data.Set as Set nubOrd :: Ord a => [a] -> [a] nubOrd xs = go Set.empty xs where go s (x:xs) | x `Set.member` s = go s xs | otherwise = x : go (Set.insert x s) xs go _ _ = []

De hecho, se ha proposed agregar nubOrd a Data.Set .


Otra forma de eliminar duplicados:

unique :: [Int] -> [Int] unique xs = [x | (x,y) <- zip xs [0..], x `notElem` (take y xs)]


Algoritmo en Haskell para crear una lista única:

data Foo = Foo { id_ :: Int , name_ :: String } deriving (Show) alldata = [ Foo 1 "Name" , Foo 2 "Name" , Foo 3 "Karl" , Foo 4 "Karl" , Foo 5 "Karl" , Foo 7 "Tim" , Foo 8 "Tim" , Foo 9 "Gaby" , Foo 9 "Name" ] isolate :: [Foo] -> [Foo] isolate [] = [] isolate (x:xs) = (fst f) : isolate (snd f) where f = foldl helper (x,[]) xs helper (a,b) y = if name_ x == name_ y then if id_ x >= id_ y then (x,b) else (y,b) else (a,y:b) main :: IO () main = mapM_ (putStrLn . show) (isolate alldata)

Salida:

Foo {id_ = 9, name_ = "Name"} Foo {id_ = 9, name_ = "Gaby"} Foo {id_ = 5, name_ = "Karl"} Foo {id_ = 8, name_ = "Tim"}


import Data.Set (toList, fromList) uniquify lst = toList $ fromList lst