Tips and Tricks for Code Golfing in Haskell

Since we have tips for golfing in C++, here’s a similar thread with tips for Haskell. Hopefully, more will contribute to it.

I’m going to follow the same caveats as in the C++ thread. Hence, no particular tips for Thor/any other particular game, no general language tips and only tricks relevant to Haskell (and like languages).

Let’s begin with the simplest one. Use operators to define binary functions. Compare

f x y=x+2*y-42
g=f 3 4

with

x!y=x+2*y-42
g=3!4

That’s a reduction with 4 characters and you squeeze 2 more chars for each new invocation of (!) (was f).

Then, remember that Haskell-functions are first-class citizens. Give them a short name instead of calling them repeatedly with the long name. Like c=cycle and use c in all places where you’d have used cycle.

Use point-free code as much as possible. f x y=head x:cycle y is worse than f=(.cycle).(:).head. To quickly get the point-free version of a function you can use lambdabot’s @pl (from pointless) on IRC on #haskell (or any other Haskell related channel).

You can even combine the above three tips to get even shorter code. That can give you tens of saved characters. Your mileage might vary.

Since you’ll need to do IO, here’s a nice function very few remember. interact :: (String -> String) -> IO. That is, you give this function a function which takes a string (the input of your code) and produces another string (the output of said code) and this interact will make sure said function is called with proper arguments and said function’s output is printed back. No more getContents, getLine, print, putStrLn and monadic binds.

Don’t use if. Use guards (and ignore the cases when they are not exhaustive). Replace True and False with 0<1 and 1<1 (or similar).

And the wicked one: let can be transformed into a lambda. let e=x a b c in z e is the same as (\e->z e)$x a b c. You might even be able to squeeze out some parens from time to time.

I’ll add more when I find more to use.

4 Likes

More tips are listed on the dedicated page on StackExchange.

Some additional tips:
Use map for a loop with its index. Use mapM instead if you need to print inside the loop. E.g.: mapM print[1..10]. Maybe you want an infinite loop as in mapM print[1..].

2 Likes

@mihai_maruseac that’s the spirit :wink:

thanks for your contribution, i’m encouraging everyone to do the same with their language of predilection.