Saltar al contenido

Por que usar null función en lugar de == [] comprobar si hay una lista vacía en Haskell?

Siéntete en la libertad de compartir nuestros tutoriales y códigos en tus redes, necesitamos de tu ayuda para ampliar nuestra comunidad.

Solución:

Deberías usar null. En la mayoría de los casos no importa, pero de todos modos es un buen hábito, porque de vez en cuando querrás comprobar si una lista de cosas no comparables está vacía. Aquí hay un ejemplo breve y nítido que muestra esta diferencia:

> null [id]
False
> [id] == []
:1:1: error:
    • No instance for (Eq (a0 -> a0)) arising from a use of ‘==’
        (maybe you haven't applied a function to enough arguments?)
    • In the expression: [id] == []
      In an equation for ‘it’: it = [id] == []

Hay una diferencia. Para usar x == []el tipo de los elementos de la lista debe ser un miembro de la Eq clase de tipo. De hecho, la verificación de la igualdad de dos listas se define mediante la declaración de instancia:

instance Eq a => Eq [a] where
    []     == []      =  True
    (x:xs) == (y:ys)  =  x == y  &&  xs == ys
    _      == _       =  False

Eso significa que no puedes usar x == [] si x es por ejemplo una lista de IO Ints.

null :: [a] -> Bool por otro lado, utiliza la coincidencia de patrones. Esto se implementa como:

null                    :: [a] -> Bool
null []                 =  True
null (_:_)              =  False

Entonces, independientemente de qué tipo sean los elementos de la lista, siempre se verificará el tipo.

Además de las buenas respuestas dadas hasta ahora, null en realidad tiene tipo

null :: Foldable t => t a -> Bool

No sé si has llegado a typeclasses en LYAH, pero en resumen es que null se puede usar no solo para listas, sino para cualquier estructura de datos que implemente null.

Esto quiere decir que usando null en un Map o un Set es válido, también.

> null Map.empty
True
> null (Map.singleton 1)
False
> null Set.empty
True
> null (Set.singleton 1)
False
> null []
True
> null [1]
False

No creo que sea especialmente común escribir funciones que deban ser tan generales, pero no está de más escribir por defecto un código más general.

Una nota al margen

En muchos casos, terminará queriendo usar una función como null para hacer un comportamiento condicional en una lista (u otra estructura de datos). Si ya sabe que su entrada es una estructura de datos específica, es más elegante simplemente hacer coincidir el patrón en su caso vacío.

Comparar

myMap :: (a -> b) -> [a] -> [b]
myMap f xs
  | null xs = []
myMap f (x:xs) = f x : myMap f xs

a

myMap' :: (a -> b) -> [a] -> [b]
myMap' f [] = []
myMap' f (x:xs) = f x : myMap' f xs

En general, debe intentar preferir la coincidencia de patrones si tiene sentido.

Aquí puedes ver las comentarios y valoraciones de los usuarios

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *