Online Book Reader

Home Category

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

By Root 451 0
comprehension that combines a list of adjectives and a list of nouns.

ghci> let nouns = ["hobo","frog","pope"]

ghci> let adjectives = ["lazy","grouchy","scheming"]

ghci> [adjective ++ " " ++ noun | adjective <- adjectives, noun <- nouns]

["lazy hobo","lazy frog","lazy pope","grouchy hobo","grouchy frog",

"grouchy pope","scheming hobo","scheming frog","scheming pope"]

We can even use list comprehensions to write our own version of the length function! We’ll call it length'. This function will replace every element in a list with 1, then add them all up with sum, yielding the length of the list.

length' xs = sum [1 | _ <- xs]

Here we use underscore (_) as a temporary variable to store the items as we draw them from the input list, since we don’t actually care about the values.

Remember, strings are lists too, so we can use list comprehensions to process and produce strings. Here’s an example of a function that takes a string and removes all the lowercase letters from it:

removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']]

The predicate here does all the work. It says that the character will be included in the new list only if it’s an element of the list ['A'..'Z']. We can load the function in GHCi and test it out:

ghci> removeNonUppercase "Hahaha! Ahahaha!"

"HA"

ghci> removeNonUppercase "IdontLIKEFROGS"

"ILIKEFROGS"

You can also create nested list comprehensions if you’re operating on lists that contain lists. For example, let’s take a list that contains several lists of numbers and remove all the odd numbers without flattening the list:

ghci> let xxs = [[1,3,5,2,3,1,2,4,5],[1,2,3,4,5,6,7,8,9],[1,2,4,2,1,6,3,1,3,2,3,6]]

ghci> [ [ x | x <- xs, even x ] | xs <- xxs]

[[2,2,4],[2,4,6,8],[2,4,2,6,2,6]]

Here the output of the outer list comprehension is another list comprehension. A list comprehension always results in a list of something, so we know that the result here will be a list of lists of numbers.

Note

You can split list comprehensions across several lines to improve their readability. If you’re not in GHCi, this can be a great help, especially when dealing with nested comprehensions.

Tuples

Tuples are used to store several heterogeneous elements as a single value.

In some ways, tuples are a lot like lists. However, there are some fundamental differences. First, as mentioned, tuples are heterogeneous. This means that a single tuple can store elements of several different types. Second, tuples have a fixed size—you need to know how many elements you’ll be storing ahead of time.

Tuples are surrounded by parentheses, and their components are separated by commas:

ghci> (1, 3)

(1,3)

ghci> (3, 'a', "hello")

(3,'a',"hello")

ghci> (50, 50.4, "hello", 'b')

(50,50.4,"hello",'b')

Using Tuples


As an example of when tuples would be useful, let’s think about how we’d represent a two-dimensional vector in Haskell. One way would be to use a two item list, in the form of [x,y]. But suppose we wanted to make a list of vectors, to represent the corners of a two-dimensional shape in a coordinate plane. We could just create a list of lists, like this: [[1,2],[8,11],[4,5]].

The problem with this method, however, is that we could also make a list like [[1,2],[8,11,5],[4,5]] and try to use it in the place of a list of vectors. Even though it doesn’t make sense as a list of vectors, Haskell has no problem with this list appearing wherever the previous list can, since both are of the same type (a list of lists of numbers). This could make it more complicated to write functions to manipulate vectors and shapes.

In contrast, a tuple of size two (also called a pair) and a tuple of size three (also called a triple) are treated as two distinct types, which means a list can’t be composed of both pairs and triples. This makes tuples much more useful for representing vectors.

We can change our vectors to tuples by surrounding them with parentheses instead of square brackets, like this: [(1,2),(8,11),(4,5)]. Now, if we try to mix pairs and triples, we get an error, like this:

ghci> [(1,2),(8,11,5),(4,5)]

Return Main Page Previous Page Next Page

®Online Book Reader