
On Feb 14, 2010, at 4:38 AM, Günther Schmidt wrote:
I've got a problem, in short my haskell code sucks. While it does work and I do manage to use higher-orderish aspects quite extensively to make my code more concise it still is nowhere abstract, always concrete and thus always with lots of boilerplate.
There is a such a thing as too much higher-ordered-ness. Every time you introduce a new higher order dispatch mechanism, you go through many of the same steps, and produce "slightly incompatible" interfaces. You're basically defining plumbing, which you might have to plumb into your existing plumbing. Boilerplate city. Instead of looking for a higher-order solution to your problem, look for a normal form to express abstract terms that solve your problem. The higher-order solution will become "obvious" when you have the right normal forms (because now you know what you're quantifying over) For example, algebraic data types are a natural encoding for tree-like structures. They can even contain things. Monads are an encoding for tree-like structures with an interface to the things the nodes contain. I'm not saying you need to use monads. I'm saying you should use them when they are the right normal form. Unfortunately, boilerplate is kind of a fact of life in Haskell, unless you use things like TemplateHaskell or SYB. After making all our nice orthogonal classes and data types in sensible normal forms, we need to join these classes and types, with functions and class instances. Taking big types down a chain of type classes is no fun. But at least all that complexity is kept in one sensible place. One thing I wish GHC would do better is deal with cyclical module dependencies more flexibly. More flexibility would mean letting us organize our code by the normal form it embodies, as opposed to the modules/types it uses. That makes code look a lot less boilerplate- ish, since the "irrelevant" but important bits can all go together.