Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation of null function

Tags:

haskell

I have to learn Haskell for university and therefor I'm using learnyouahaskell.com for the beginning.
I always used imperative languages so I decided to practice Haskell by coding a lot more than I would for other languages.
I started to implement several functions to work with lists such as head, tail, init,...
At some point I looked up the implementations of these functions to compare to mine and I stumbled upon the null function defined in List.lhs.

null's implementation:

-- | Test whether a list is empty.
null                    :: [a] -> Bool
null []                 =  True
null (_:_)              =  False

my implementation:

mNull :: [a] -> Bool
mNull []        = True
mNull _         = False

I know there are no stupid questions even for such simple questions :)
So my question is why the original implementation uses (_:_) instead of just _?
Is there any advantage in using (_:_) or are there any edge cases I don't know of?
I can't really imagine any advantage because _ catches everything.

like image 715
TorbenJ Avatar asked Jan 14 '15 11:01

TorbenJ


People also ask

What does the null function do?

Returns a Boolean value that indicates whether an expression contains no valid data (Null). The required expressionargument is a Variant containing a numeric expression or string expression. IsNull returns True if expression is Null; otherwise, IsNull returns False.

Is null () in R?

The R function is. null indicates whether a data object is of the data type NULL (i.e. a missing value). The function returns TRUE in case of a NULL object and FALSE in case that the data object is not NULL.

IS null a special function in C++?

Null functions are nothing but a way to assign value to the pointer variable in c++. We can also do dereferencing of our null pointers in c++, but this will lead to unusual behavior of the program.

What is the type of null in C?

The C and C++ languages have a null character (NUL), a null pointer (NULL), and a null statement (just a semicolon (;)). The C NUL is a single character that compares equal to 0. The C NULL is a special reserved pointer value that does not point to any valid data object.


2 Answers

You can't just turn the clauses around with your solution:

mNull' :: [a] -> Bool mNull' _  = False mNull' [] = True 

this will always yield False, even if you pass an empty list. Because the runtime doesn't ever consider the [] clause, it immediately sees _ matches anything. (GHC will warn you about such an overlapping pattern.)

On the other hand,

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

still works correctly, because (_:_) fails to match the particular case of an empty list.

That in itself doesn't really give the two explicit clauses an advantage. However, in more complicated code, writing out all the mutually excluse options has one benefit: if you've forgotten one option, the compiler can also warn you about that! Whereas a _ can and will just handle any case not dealt with by the previous clauses, even if that's not actually correct.

like image 114
leftaroundabout Avatar answered Sep 30 '22 15:09

leftaroundabout


Because _ literally means anything apart from explicitly specified patterns. When you specify (_:_) it means anything which can be represented as a list containing at least 1 element, without bothering with what or even how many elements the list actually contains. Since the case with an explicit pattern for empty list is already present, (_:_) might as well be replaced by _.

However, representing it as (_:_) gives you the flexibility to not even explicitly pass the empty list pattern. In fact, this will work:

-- | Test whether a list is empty.
null                    :: [a] -> Bool    
null (_:_)              =  False
null _                  =  True

Demo

like image 35
shree.pat18 Avatar answered Sep 30 '22 15:09

shree.pat18