Online Book Reader

Home Category

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

By Root 559 0
birds landing on and flying away from the pole and see if Pierre is still at it after a certain number of bird arrivals and departures. For instance, we want to see what happens to Pierre if first one bird arrives on the left side, then four birds occupy the right side, and then the bird that was on the left side decides to fly away.

Code, Code, Code


We can represent the pole with a simple pair of integers. The first component will signify the number of birds on the left side and the second component the number of birds on the right side:

type Birds = Int

type Pole = (Birds, Birds)

First, we made a type synonym for Int, called Birds, because we’re using integers to represent how many birds there are. And then we made a type synonym (Birds, Birds) and called it Pole (not to be confused with a person of Polish descent).

Now, how about adding functions that take a number of birds and land them on one side of the pole or the other?

landLeft :: Birds -> Pole -> Pole

landLeft n (left, right) = (left + n, right)

landRight :: Birds -> Pole -> Pole

landRight n (left, right) = (left, right + n)

Let’s try them out:

ghci> landLeft 2 (0, 0)

(2,0)

ghci> landRight 1 (1, 2)

(1,3)

ghci> landRight (-1) (1, 2)

(1,1)

To make birds fly away, we just had a negative number of birds land on one side. Because landing a bird on the Pole returns a Pole, we can chain applications of landLeft and landRight:

ghci> landLeft 2 (landRight 1 (landLeft 1 (0, 0)))

(3,1)

When we apply the function landLeft 1 to (0, 0) we get (1, 0). Then we land a bird on the right side, resulting in (1, 1). Finally, two birds land on the left side, resulting in (3, 1). We apply a function to something by first writing the function and then writing its parameter, but here it would be better if the pole went first and then the landing function. Suppose we make a function like this:

x -: f = f x

We can apply functions by first writing the parameter and then the function:

ghci> 100 -: (*3)

300

ghci> True -: not

False

ghci> (0, 0) -: landLeft 2

(2,0)

By using this form, we can repeatedly land birds on the pole in a more readable manner:

ghci> (0, 0) -: landLeft 1 -: landRight 1 -: landLeft 2

(3,1)

Pretty cool! This version is equivalent to the one before where we repeatedly landed birds on the pole, but it looks neater. Here, it’s more obvious that we start off with (0, 0) and then land one bird on the left, then one on the right, and finally, two on the left.

I'll Fly Away


So far so good, but what happens if ten birds land on one side?

ghci> landLeft 10 (0, 3)

(10,3)

Ten birds on the left side and only three on the right? That’s sure to send poor Pierre falling through the air! This is pretty obvious here, but what if we had a sequence of landings like this:

ghci> (0, 0) -: landLeft 1 -: landRight 4 -: landLeft (-1) -: landRight (-2)

(0,2)

It might seem as if everything is okay, but if you follow the steps here, you’ll see that at one time there are four birds on the right side and no birds on the left! To fix this, we need to take another look at our landLeft and landRight functions.

We want the landLeft and landRight functions to be able to fail. We want them to return a new pole if the balance is okay but fail if the birds land in a lopsided manner. And what better way to add a context of failure to value than by using Maybe! Let’s rework these functions:

landLeft :: Birds -> Pole -> Maybe Pole

landLeft n (left, right)

| abs ((left + n) - right) < 4 = Just (left + n, right)

| otherwise = Nothing

landRight :: Birds -> Pole -> Maybe Pole

landRight n (left, right)

| abs (left - (right + n)) < 4 = Just (left, right + n)

| otherwise = Nothing

Instead of returning a Pole, these functions now return a Maybe Pole. They still take the number of birds and the old pole as before, but then they check if landing that many birds on the pole would throw Pierre off balance. We use guards to check if the difference between the number of birds on the new pole is less than 4. If it is, we wrap the new pole in a Just and return that.

Return Main Page Previous Page Next Page

®Online Book Reader