Prelude (euler !! 0)

Back from another hiatus. Winter break has come at long last, so I have some free time. After a few weeks of relaxing, I couldn't stand doing nothing any longer, so I decided to learn Haskell. It's completely different from the other languages I've programmed in; Perl, C++, and BASIC are all imperative languages, while Haskell is a functional language. I suspect it will be a while before I fully comprehend what it means for a language to be functional. Anyway, here's some music; let's get to know Haskell the same way we got to know Perl: Project Euler!


If you recall, Euler problem 1 asks that we find the sum of all numbers under 1000 that are divisible by 3 or 5. In Haskell, we'll be solving a lot of these types of problems using list comprehensions. A list comprehension is essentially a way of narrowing down a broad range of values, using some specific criteria.
Here, our range is the numbers 1 to 1000. We can use the syntax 1..1000 to represent this range, just as we did in Perl. Our criterion is the expression:
x `mod` 3 == 0 || x `mod` 5 == 0. The graves around mod signify that we are using it as an infix function; normally, a function is followed by its arguments, i.e. mod x 3. In mathematics (and Perl, with %), however, we use the syntax x mod 3. So the infix operator simply allows us to emulate this syntax and make the statement a bit more readable.
The final code for our list comprehension looks like this:

[x | x <- [1..999], x `mod` 3 == 0 || x `mod` 5 == 0]

The output of a list comprehension is, unsurprisingly, a list. The initial x | means "the values of the resulting list will be x, where...", and the x <- [1..999] means we are drawing potential values of x from the range 1 to 999. Following that are the criteria that x must satisfy. Note that we could also have written:

[ if x `mod` 3 == 0 || x `mod` 5 == 0 then x else 0 | x <- [1..999]]

Haskell, like most functional languages, excels at manipulating lists. You might say that lists are to Haskell what strings are to Perl! Fortunately, most of the Euler problems involve sequences (i.e. lists) in some way, so Haskell is a good choice for solving them.
At any rate, we still have to sum up all the values of the resulting list. This is easily accomplished with the sum function (oh how I have longed for such a function in Perl...). We simply apply sum to our list comprehension and we have our answer:

problem1 = sum [x | x <- [1..999], x `mod` 3 == 0 || x `mod` 5 == 0]

I think I'll stop there for today, since problem 2 involves the Fibonacci sequence, which has a neat (but perhaps confusing) Haskell implementation.

EDIT: While list comprehensions are cool, they aren't exactly very "functional;" the preferred way to do things (especially things as simple as this) is to use filter:

problem1 = sum $ filter (threeOrFive) [1..999] where
    threeOrFive x = x `mod` 3 == 0 || x `mod` 3 == 0

Leave a Reply

Theme: Esquire by Matthew Buchanan.