Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking for empty list in Haskell: Is (length list == 0) or (list == []) more efficient?

Tags:

Say I want to check if a list is empty in a guard in Haskell there are two options:

  1. length list == 0
  2. list == []

Which of these two logical tests are more efficient? I'm inclined to say the empty list test because relies on more basic constructs rather than the prelude function length but I'm not sure.

like image 615
J-S Avatar asked Apr 07 '16 05:04

J-S


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.

How are lists defined in Haskell?

In Haskell, lists are a homogenous data structure. It stores several elements of the same type. That means that we can have a list of integers or a list of characters but we can't have a list that has a few integers and then a few characters. And now, a list!


2 Answers

length list == 0 needs to traverse the whole list to get its length, which means it is O(n). list == [] yields an Eq constraint on the element type. null list runs in constant time and has no typeclass constraints.

However, there is a neat trick to do something like length list == 0 which has the advantage that it generalizes nicely to length list1 == length list2 without going through the longer list: you can use genericLength with a sufficiently lazy representation of natural numbers so that comparison will only force traversing the shorter of the lists.

One example is to use the Natural type:

import Data.Number.Natural
import Data.List (genericLength)

nats :: [Int]
nats = iterate succ 0

areThereTenNats :: Bool
areThereTenNats = genericLength nats >= (10 :: Natural)
like image 59
Cactus Avatar answered Sep 28 '22 06:09

Cactus


You can check if your list is empty in constant time with null list, which returns a boolean.

Prelude> null []
True
Prelude> null [1]
False
Prelude> null ""
True
Prelude> null "Test"
False
like image 20
manonthemat Avatar answered Sep 28 '22 07:09

manonthemat