Taking and Dropping

In our first article on list functions, we looked at some boolean functions that allowed for filtering lists based on particular conditions. Of course, filter is the primary function we might use for that. But sometimes, you're only concerned with how long the pattern is at the start of your list. You want to include some of the elements at the start, or else drop them. Today we'll look at variations of "take" and "drop" functions that let you do this.

The most basic versions of these functions allow you to specify the number of elements you're interested. The "take" function takes an integer and your list and produces the first "n" elements, while "drop" will give you the remainder of the list besides these elements:

take :: Int -> [a] -> [a]

drop :: Int -> [a] -> [a]

Getting the 5 smallest numbers in a list is easy when you combine take and sort.

>> let myList = [2, 5, 6, 3, 1, 9, 8, 7, 4]
>> take 5 (sort myList)
[1, 2, 3, 4, 5]
>> drop 5 (sort myList)
[6, 7, 8, 9]

This is simple enough, but sometimes you want to do something a little trickier. You want to take all the elements of the list from the front, but only as long as they satisfy a particular condition. In this case, you want takeWhile and its comrade, dropWhile. Each of these takes a predicate function instead of a number.

takeWhile :: (a -> Bool) -> [a] -> [a]

dropWhile :: (a -> Bool) -> [a] -> [a]

A couple simple use cases might be removing the "odd" numbers from the start of a list, or grabbing only the lowercase letters of a variable name that you've parsed.

>> let isOdd x = x `mod` 2 == 1
>> dropWhile isOdd [5, 7, 9, 2, 1, 3, 4]
[2, 1, 3, 4]
>> takeWhile isLower "variableNameInCamelCase"
"variable"

Now in the Data.List.Extra library, there are some additional variations that allow for taking and dropping from the end:

takeWhileEnd :: (a -> Bool) -> [a] -> [a]

dropWhileEnd :: (a -> Bool) -> [a] -> [a]

We'll cover more of these kinds of "extra" functions later in the year. But these two examples do the same thing as their counterparts, just operating from the end of the list instead of the start.

>> isOdd x = x `mod` 2 == 1
>> takeWhileEnd isOdd [2, 4, 1, 6, 7, 9]
[7, 9]
>> dropWhileEnd isOdd [2, 4, 1, 6, 7, 9]
[2, 4, 1, 6]

We'll soon be moving on from list manipulations to a new topic. To keep up to date, make sure you keep checking this blog every Monday and Thursday, or subscribe to our monthly newsletter! If you're just starting out learning Haskell, subscribing will give you access to our Beginners Checklist which will help you learn the basics and get going!

Previous
Previous

To Infinity and Beyond!

Next
Next

Math-y List Operations