Reputation: 1072
cube (x,y,z) =
filter (pcubes x) cubes
cubes = [(a,b,c) | a <- [1..30],b <- [1..30],c <- [1..30]]
pcubes x (b,n,m) = (floor(sqrt(b*n)) == x)
so this code works, cubes
makes a list of tuples,pcubes is used with filter to filter all the cubes in which floor(sqrt(b*n)) == x
is satisfied,but the person who has modified my code wrote pcubes x
in filter (pcubes x) cubes
,how does this work.pcubes x
makes a function that will initial the cubes x (b,n,m)
that will take in a tuple and output a bool.the bool will be used in the filter function. How does this sort of manipulation happen? how does pcubes x
access the (b,n,m)
part of the function?
Upvotes: 0
Views: 123
Reputation: 11913
In Haskell, we don't usually use tuples (ie: (a,b,c)
) to pass arguments to functions. We use currying.
Here's an example:
add a b = a + b
Here add
is a function that takes a number, the returns another function that takes a number, then returns a number. We represent it's type as so:
add :: Int -> (Int -> Int)
Because of the way ->
behaves, we can remove the parentheses in this case:
add :: Int -> Int -> Int
It is called like this:
(add 1) 2
but because of the way application works, we can just write:
add 1 2
Doesn't that look like our definition above, of the form add a b
...?
Your function pcubes
is similar. Here's how I'd write it:
pcubes x (b,n,m) = floor (sqrt (b*n)) == x
And as someone else said, it's type could be represented as:
pcubes :: Float -> (Float, Float, Float) -> Bool
When we write pcubes 1
the type becomes:
pcubes 1 :: (Float, Float, Float) -> Bool
Which, through currying, is legal, and can quite happily be used elsewhere.
I know, this is crazy black functional magic, as it was for me, but before long I guarantee you'll never want to go back: curried functions are useful.
A note on tuples: Expressions like (a,b,c)
are data . They are not purely function-argument expressions. The fact that we can pull it into a function is called pattern matching, though it's not my turn to go into that.
Upvotes: 4