Online Book Reader

Home Category

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

By Root 486 0
next to the right angle are labeled a and b, and the side opposite the right angle is labeled c. We call that side the hypotenuse.

As a first step, let’s generate all possible triples with elements that are less than or equal to 10:

ghci> let triples = [ (a,b,c) | c <- [1..10], a <- [1..10], b <- [1..10] ]

We’re drawing from three lists on the right-hand side of the comprehension, and the output expression on the left combines them into a list of triples. If you evaluate triples in GHCi, you’ll get a list that is 1,000 entries long, so we won’t show it here.

Next, we’ll filter out triples that don’t represent right triangles by adding a predicate that checks to see if the Pythagorean theorem (a^2 + b^2 == c^2) holds. We’ll also modify the function to ensure that side a isn’t larger than the hypotenuse c, and that side b isn’t larger than side a:

ghci> let rightTriangles = [ (a,b,c) | c <- [1..10], a <- [1..c], b <- [1..a],

a^2 + b^2 == c^2]

Notice how we changed the ranges in the lists that we draw values from. This ensures that we don’t check unnecessary triples, such as ones where side b is larger than the hypotenuse (in a right triangle, the hypotenuse is always the longest side). We also assumed that side b is never larger than side a. This doesn’t harm anything, because for every triple (a,b,c) with a^2 + b^2 == c^2 and b > a that is left out of consideration, the triple (b,a,c) is included—and is the same triangle, just with the legs reversed. (Otherwise, our list of results would contain pairs of triangles that are essentially the same.)

Note

In GHCi, you can’t break up definitions and expressions across multiple lines. In this book, however, we occasionally need to break up a single line so the code can all fit on the page. (Otherwise the book would have to be really wide, and it wouldn’t fit on any normal shelf—and then you’d have to buy bigger shelves!)

We’re almost done. Now, we just need to modify the function to only output the triangles whose perimeter equals 24:

ghci> let rightTriangles' = [ (a,b,c) | c <- [1..10],

a <- [1..c], b <- [1..a], a^2 + b^2 == c^2, a+b+c == 24]

ghci> rightTriangles'

[(6,8,10)]

And there’s our answer! This is a common pattern in functional programming: you start with a certain set of candidate solutions, and successively apply transformations and filters to them until you’ve narrowed the possibilities down to the one solution (or several solutions) that you’re after.

Chapter 2. Believe the Type

One of Haskell’s greatest strengths is its powerful type system.

In Haskell, every expression’s type is known at compile time, which leads to safer code. If you write a program that tries to divide a Boolean type with a number, it won’t compile. This is good because it’s better to catch those kinds of errors at compile time, rather than having your program crash later on. Everything in Haskell has a type, so the compiler can reason quite a lot about your program before compiling it.

Unlike Java or Pascal, Haskell has type inference. If we write a number, for example, we don’t need to tell Haskell it’s a number, because it can infer that on its own.

So far, we’ve covered some of the basics of Haskell with only a very superficial glance at types, but understanding the type system is a very important part of learning Haskell.

Explicit Type Declaration


We can use GHCi to examine the types of some expressions. We’ll do that by using the :t command which, followed by any valid expression, tells us its type. Let’s give it a whirl:

ghci> :t 'a'

'a' :: Char

ghci> :t True

True :: Bool

ghci> :t "HELLO!"

"HELLO!" :: [Char]

ghci> :t (True, 'a')

(True, 'a') :: (Bool, Char)

ghci> :t 4 == 5

4 == 5 :: Bool

The :: operator here is read as “has type of.” Explicit types are always denoted with the first letter in uppercase. 'a' has a type of Char, which stands for character. True is a Bool, or a Boolean type. "HELLO!", which is a string, shows its type as [Char]. The square brackets denote a list, so we read that as it being a list of characters. Unlike lists, each tuple

Return Main Page Previous Page Next Page

®Online Book Reader