
On Wed, Jul 20, 2011 at 11:45:52PM +1000, Clockwork PC wrote:
Greetings Haskell community,
This is my first ever post so please be gentle...
Hi Alexander, welcome! I hope you will find that people here are gentle whether it is your first post or 500th.
Defined my function:
Prelude> let rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10], a^2 + b^2 == c^2 ]
Tested my function:
Prelude> rightTriangles [(4,3,5),(3,4,5),(8,6,10),(6,8,10)]
Looks good.
Now, I want to define a refinement of this that will only select values whose total is 24.
I could write it so:
let rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10], a^2 + b^2 == c^2,* a+b+c == 24*]
However, it seems like a bit of a waste if I already have "rightTriangles" defined.
Indeed! In general Haskell offers lots of abstraction that makes it easy not to repeat yourself, so this is a good intuition.
I tried a few things, but none of them worked:
Prelude> let rightTriangles` = rightTriangles, a+b+c == 24
First of all, backtick ` cannot be used as part of an identifier name. Instead you probably want rightTriangles' (with a single quote). The second issue is that there is no way to "extend" a list comprehension. Once you have defined a list using a list comprehension, all you have is the list -- there is no longer any way to "reach inside" the definition and see that it was defined using a list comprehension, much less extend or alter the definition. So we have to make do with manipulating the list rightTriangles itself. First, you could simply write a new list comprehension, pulling values from the original rightTriangles list, like so: rightTriangles' = [ (a,b,c) | (a,b,c) <- rightTriangles, a+b+c = 24 ] Or you could use the 'filter' function. As its first argument it expects a *function* which returns a Bool (True or False) for each element in the list, specifying whether to keep it (True) or throw it away (False). As its second argument it takes the list you want to filter. So: rightTriangles' = filter sum24 rightTriangles where sum24 (a,b,c) = (a+b+c) == 24 Here the sum24 function decides whether to keep each triple (a,b,c): we only want to keep those whose sum is equal to 24. -Brent