loading...

Little partial application challenge in Haskell

github logo ・1 min read

Correct a function that maps a list of negative numbers.

Input: [-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0]

Output: [-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1]

A function that I wrote but that results in a mistake.

map (-1) [-10..0]

This can be solved using lambda

map (\x -> x - 1) [-10..0]

The challenge is to solve it with partial application.

twitter logo DISCUSS (8)
markdown guide
 

Personally, I think the lambda solution is perfect without partial application because it is easy to read. But for the purposes of this challenge, here is a partial application solution.

map (flip (-) 1) [-10..0]

I don't have a Haskell environment to test with, but I tested the equivalent in F#.

 

It works, I checked. That's a pretty clever solution.

 

Doh, I missed the more obvious solution. 🙃

map ((+) -1) [-10..0]

Very close.

This one gives:

<interactive>:1:1: error:
     Non type-variable argument in the constraint: Num (a -> a -> a)
      (Use FlexibleContexts to permit this)
     When checking the inferred type
        it :: forall a. (Num (a -> a -> a), Num a, Enum a) => [a -> a]

Huh, this works verbatim in F#.

List.map ((+) -1) [-10..0]

No HKT or type classes, so each structure in F# has its own map implementation.

I'm not sure why it doesn't work in Haskell tbh. Possibilities are that (+) is not recognized as integer addition. Or that the negative sign on -1 is parsed as a function.

Indeed, Haskell is picky.

map (+ (-1)) [-10..0]

is a working solution.

Also there is another one, specifically to address the problem with the minus sign:

map (subtract 1) [-10..0]

Ah. I wonder why -1 requires parens. I also thought that you can turn an inline operator into a regular function by putting parens around it. (And vice versa with back ticks). I guess I should do my own Haskell homework instead of asking here. :)

If I remember accurately it is because anything that is not a value in haskell is a function.
So without the parentheses it can't know if -1 means the function - applied to some other value and the number one like1-1( function - applied to 1 and 1 ) or the value -1, so the way they solved it is to have it be the function, therefore you would be missing an argument or you would be passning a wrong type.
When you want a value you would have to use (-1) so then it knows that you trully mean the value -1.

PS: This is my first comment I hope I didn't come out sounding a but too "know it all" or trying to sound smart, I just wanted to explain it the best I can.

Classic DEV Post from Aug 22 '19

Where in the world do you DEV?

Show off where in the world you DEV from!

Anton profile image
Born into being.

Do you prefer sans serif over serif?

You can change your font preferences in the "misc" section of your settings. ❤️