Reputation: 442
I am new to Haskell and functionall programming and am a little confused. Why can not I curry an anonymous function, or is it even possible?
I have the following piece of code:
largestDivisible :: (Integral a) => a -> a
largestDivisible x
| x <= 0 = error "NOT A VALID VALUE"
| otherwise = head (myFilter (f x) [x-1, x-2..1])
where f x y= x `mod` y == 0
When I try to write it like this:
largestDivisible :: (Integral a) => a -> a
largestDivisible x
| x <= 0 = error "NOT A VALID VALUE"
| otherwise = head (myFilter (\ x y = x `mod` y == 0) [x-1, x-2..1])
Then I get the following error if I try to load it into the GHCi I get the following error:
ListStuff.hs:85:35: error:
• Couldn't match expected type ‘Bool’ with actual type ‘a -> Bool’
• The lambda expression ‘\ x y -> (mod x y == 0)’
has two arguments,
but its type ‘a -> Bool’ has only one
In the first argument of ‘myFilter’, namely
‘(\ x y -> (mod x y == 0))’
In the first argument of ‘head’, namely
‘(myFilter (\ x y -> (mod x y == 0)) [x - 1, x - 2 .. 1])’
• Relevant bindings include
x :: a (bound at ListStuff.hs:83:19)
largestDivisible' :: a -> a (bound at ListStuff.hs:83:1)
Failed, modules loaded: none.
Upvotes: 1
Views: 273
Reputation: 116139
The code
| otherwise = head (myFilter (f x) [x-1, x-2..1])
where f x y= x `mod` y == 0
is equivalent to
| otherwise = head (myFilter (f x) [x-1, x-2..1])
where f = \x y -> x `mod` y == 0
which is equivalent to
| otherwise = head (myFilter ((\x y -> x `mod` y == 0) x) [x-1, x-2..1])
-- ^^^
Note that the application of x
still remains there! We can further simplify by applying the anonymous function (a beta step):
| otherwise = head (myFilter (\y -> x `mod` y == 0) [x-1, x-2..1])
Upvotes: 5
Reputation: 67743
x
is an argument to largestDivisible
, but you don't need to pass it as an argument to your lambda. The lambda can get x
from the captured context, and only needs y
as an argument.
The first version passes the partially-applied f x
to myFilter
, and that - with the first argument given - is a unary function.
The second version tries passing a lambda of two arguments, without using partial application to get a suitable function first.
Either use partial application as in your first example, or just write a lambda of one argument (y
).
Upvotes: 5