Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use null function instead of == [] to check for empty list in Haskell?

I am reading through the "Starting Out" chapter of Learn You a Haskell for Great Good!. It says:

null checks if a list is empty. If it is, it returns True, otherwise it returns False. Use this function instead of xs == [] (if you have a list called xs)

I tried in ghci:

xs = []      -- and then,  xs == [] null xs 

Both of them are True.

I wonder what's the difference.

Should I use the null function instead of == [] and why?

like image 962
徐保钰 Avatar asked Jul 14 '19 16:07

徐保钰


People also ask

Can you have an empty list in Haskell?

Get Programming with HaskellYou can't return an empty list, because an empty list is the same type as the elements of the list.

How do you know if a list has equal Haskell?

You can just use == on them directly. This means that lists instantiate Eq as long as the element type also instantiates Eq , which is the case for all types defined in the standard Prelude except functions and IO actions.


Video Answer


2 Answers

You should use null. In most cases it doesn't matter, but it is a good habit to get into anyway, because occasionally you may want to check if a list of non-comparable things is empty. Here is a short, crisp example showing this difference:

> null [id] False > [id] == [] <interactive>: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] == [] 
like image 191
Daniel Wagner Avatar answered Oct 18 '22 22:10

Daniel Wagner


There is a difference. In order to use x == [], the type of the elements of the list should be a member of the Eq typeclass. Indeed, checking the equality of two lists is defined by the instance declaration:

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

That means that you can not use x == [] if x is for example a list of IO Ints.

null :: [a] -> Bool on the other hand, uses pattern matching. This is implemented as:

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

So regardless what type the elements of the list are, it will always typecheck.

like image 37
Willem Van Onsem Avatar answered Oct 18 '22 22:10

Willem Van Onsem