Spark Monkay
Spark Monkay

Reputation: 442

Curry Anonymous Function

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

Answers (2)

chi
chi

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

Useless
Useless

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

Related Questions