Online Book Reader

Home Category

Learn You a Haskell for Great Good! - Miran Lipovaca [7]

By Root 391 0
The only difference between the two is that writing out long enumeration sequences manually is stupid.

Here are a few more examples:

ghci> [1..20]

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

ghci> ['a'..'z']

"abcdefghijklmnopqrstuvwxyz"

ghci> ['K'..'Z']

"KLMNOPQRSTUVWXYZ"

You can also specify a step between items in your range. What if we want a list of every even number between 1 and 20? Or every third number between 1 and 20? It’s simply a matter of separating the first two elements with a comma and specifying the upper limit:

ghci> [2,4..20]

[2,4,6,8,10,12,14,16,18,20]

ghci> [3,6..20]

[3,6,9,12,15,18]

While they are pretty convenient, ranges with steps aren’t always as smart as people expect them to be. For example, you can’t enter [1,2,4,8,16..100] and expect to get all the powers of 2 that are no greater than 100. For one thing, you can only specify a single step size. Also, some sequences that aren’t arithmetic can’t be specified unambiguously by giving only their first few terms.

Note

To make a list with all the numbers from 20 down to 1, you can’t just type [20..1], you have to type [20,19..1]. When you use a range without steps (like [20..1]), Haskell will start with an empty list and then keep increasing the starting element by one until it reaches or surpasses the end element in the range. Because 20 is already greater than 1, the result will just be an empty list.

You can also use ranges to make infinite lists by not specifying an upper limit. For example, let’s create a list containing the first 24 multiples of 13. Here’s one way to do it:

ghci> [13,26..24*13]

[13,26,39,52,65,78,91,104,117,130,143,156,169,

182,195,208,221,234,247,260,273,286,299,312]

But there’s actually a better way—using an infinite list:

ghci> take 24 [13,26..]

[13,26,39,52,65,78,91,104,117,130,143,156,169,182,

195,208,221,234,247,260,273,286,299,312]

Because Haskell is lazy, it won’t try to evaluate the entire infinite list immediately (which is good because it would never finish anyway). Instead, it will wait to see which elements you need to get from that infinite list. In the above example, it sees that you just want the first 24 elements, and it gladly obliges.

Here are a few functions that can be used to produce long or infinite lists:

cycle takes a list and replicates its elements indefinitely to form an infinite list. If you try to display the result, it will go on forever, so make sure to slice it off somewhere:

ghci> take 10 (cycle [1,2,3])

[1,2,3,1,2,3,1,2,3,1]

ghci> take 12 (cycle "LOL ")

"LOL LOL LOL "

repeat takes an element and produces an infinite list of just that element. It’s like cycling a list with only one element:

ghci> take 10 (repeat 5)

[5,5,5,5,5,5,5,5,5,5]

replicate is an easier way to create a list composed of a single item. It takes the length of the list and the item to replicate, as follows:

ghci> replicate 3 10

[10,10,10]

One final note about ranges: watch out when using them with floating-point numbers! Because floating-point numbers, by their nature, only have finite precision, using them in ranges can yield some pretty funky results, as you can see here:

ghci> [0.1, 0.3 .. 1]

[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]

I'm a List Comprehension

List comprehensions are a way to filter, transform, and combine lists.

They’re very similar to the mathematical concept of set comprehensions. Set comprehensions are normally used for building sets out of other sets. An example of a simple set comprehension is: { 2 · x|x ∈ N, x ≤ 10}. The exact syntax used here isn’t crucial—what’s important is that this statement says, “take all the natural numbers less than or equal to 10, multiply each one by 2, and use these results to create a new set.”

If we wanted to write the same thing in Haskell, we could do something like this with list operations: take 10 [2,4..]. However, we could also do the same thing using list comprehensions, like this:

ghci> [x*2 | x <- [1..10]]

[2,4,6,8,10,12,14,16,18,20]

Let’s take a closer look at the list

Return Main Page Previous Page Next Page

®Online Book Reader