atomically do
v <- readTVar tv
writeTVar tv $! v + 1
withForeignPtr fptr \ptr -> c_memcpy buf ptr size
Since whitespace is used for function application "f x", code like this would require mental effort on my part to realise that, for example, "withForeignPointer" isn't being called with 7 arguments.I really don't see why so much effort is spent on infix syntax, precedence rules, fully-applied "$", etc. (not to mention the associated bikeshedding), all to remove the requirement of a few parentheses.
Whilst I can perhaps entertain the notion that Lisp-style, fully-parenthesised syntax might annoy some people (personally I find it quite pleasing), I think this level of syntax-fiddling is a solution worse than the problem.
Keeping track of precedence rules is the kind of task computers are good at but humans not so much; I don't know why we invent these schemes to impose on ourselves, when we could just wrap a couple of parens around the tricky bits. (In fact, I do this; but hlint tells me off!)