My main point is simply that most of the folks that do not see the benefit of currying, are not likely to be swayed by this. I muddied that by bringing up Duff's device.
I suppose that's fair. The core problem is that the benefits of currying depend to some degree on having amenable syntax, and this means that all the examples are going to seem foreign to people.
This same thought is made ridiculously clear when you try and use closure like structures in java. Especially if you have folks insisting on the @Override nonsense. Compared to languages that make full use of them, where you have to try and look for them to spot them. (Closures, that is.)
In particular, it naturally splits apart the different function calls. So you can look at the parts separately: L.intercalate "\n", cut (b'-b+1), map toChar, elems arr. Now you have a nice little pipeline.
Perhaps to somebody without Haskell experience, the version with parentheses would be easier to understand:
However, in general, I find the $ version easier to follow.I also think that this version is better than the same code broken up into arbitrary temporary variables. The pipeline is short and clear; adding temporary bindings would just give me more things to keep in my mind at the same time.
One way to think about this is that the $ is very similar to the | in bash, just backwards. So in a bash-like pseudocode, this is something like:
Hopefully that clarifies the structure of the code and why that structure is actually very reasonable.Basically, my point is that the given code is clear and simple; chances are you find it hard to read because Haskell is somewhat foreign and not because the given code is particularly complicated or obfuscated. In fact, I think this way of writing the code is clearer than what you would get in most other languages because it forms a very clear sequence of transformations on the input.