While bitching about make with a friend...
This is rather nonintuitive at first glance, but how clean a piece of code looks has relatively little to do with how much the code does, or what it does.
What makes code easy to read is its information density. This is as much a cognitive psych measure as a engineering matter. All that Python and Haskell code where the whitespace is part of the syntax? A lot of people hate it, but the adoption of that practice is gaining traction. I strongly suspect that this is because it is easier for your eyes to perceive where one routine ends and where another begins.
There is a Goldilocks situation with regards to information density. Just like most people can optimally remember about 5-7 things at a time, we can optimally process information at a narrow range of rates, so the code should neither be too dense, nor too terse. If it is too dense, it's tricky. If it's too sparse, then you have to scroll through too much of it to get the idea of what it does, such that you may actually need your memory buffer in order to process it.
So how might we make some recommendations based on this and other tenets of Information Design?
Corner cases and nontrivial wrappers need to be kept track of, so they tally up into the 5-7 things you can keep in your memory buffer. No function or routine should have more than a few of these.
People perceive similar looking items to be similar in function, regardless of whether they are or not, so...
A. If you have a bunch of routines that are similar, they should be presented in list format.
B. Anytime you have something that is different, that breaks the pattern, you should separate it away with whitespace.
C. On the other hand, if all the routines are markedly different in function, it should also be ok to present them in listlike imperative style, so long as there aren't more than 5 or 6 of them at a time.
D. Those cascading nested Nothing/Just matches? Please don't. That should really be aligned imperative style, even if it means more lines will be necessary. The same reasoning goes for nested If/Else, but this is where Haskell's monads really shine through. If you are doing imperative work, it's much cleaner to write a wrapper, Bool -> m (), that escapes to the appropriate exception, and such a wrapper would be uneconomical in most other languages.
E. This applies particularly to all those pieces of code where you have some pure stuff being wrapped in something monadic, and the pure stuff could've stood on its own. Changes in purpose count towards information density, so in those cases where there actually is a separation between pure and monadic, it should be seen visually in the whitespace.
Anytime you have long lists of anything, please dump them elsewhere in their own file. People shouldn't have to switch gears within a single file. The information density of a single file should be relatively uniform, because information density is a meta variable.
More is less sometimes. Thanks to arrows, functors and monads, you can do all sorts of stuff with (.), <$>, second and return? Just because you can doesn't mean you shouldn't label it with intermediate terms. This applies to partial function applications especially. When you label it, people only have to remember the label, not the detail of the implementation. All that glue can obscure what something does.
Long lines that smack or exceed the 80-column limit are not terribly bad if they are either the function definition/args or the "return statement" (if you are using let..in syntax). Long lines, where they exist, should delimit the boundaries of a function, unless you are using where syntax, in which case they should just delimit the start of the function. Avoid multiple, consecutive long lines, because one long line is already visually attention grabbing. You can re-think the 80-column rule under these considerations.
That's all I can think of for now, but if you remember form follows function, then you should understand that what your code looks like to a non-programmer should reflect what it actually means, structurally, to you.