
On May 15, 2006, at 11:14 AM, Aditya Siram wrote:
I have been working with a Haskell text for the past couple of months or so and I have some general problem solving questions.
1. Is there a way to output intermediate values of a calculation? As an imperative programmer I have become used to using "System.out"'s or 'cout's to check that my function works as intended. I can see no easy way to do that in Haskell. The only solution I could come up with was to avoid using nested functions except for the most trivial expressions and test all expressions in the interpreter. This approach seems to make my code ugly and less readable.
Two responses here: 1) Check out Debug.Trace in the standard libs. (http:// www.haskell.org/ghc/docs/latest/html/libraries/base/Debug- Trace.html) It lets you insert debugging messages into pure code. Be warned, its a little tricky to use; your message will only be printed _when_and_if_ the thing you "attach" the message to is evaluated. 2) I'm not sure exactly what you mean by "nested functions", but writing small functions and composing them together to do larger tasks is a pretty Haskellish way to approach things. As you noted, this lets you easily test subparts of your computation, and it's generally considered good style. Appropriate use of the composition operator (.) or of monads can make function composition more readable. Creating intermediate representations and writing functions that transform data between these representations is a good way to structure programs that allows this compositional style. See: http:// www.haskell.org/hawiki/IntermediateRepresentation
2. Haskell is great because it makes abstracting from problem very easy. For example, if the problem asks for the area of a square, why not write a function to compute the area of all polygons? find myself falling into the trap of generalizing to the point that a simple problem becomes quite a bit harder . From a general design perspective should I concentrate on abstracting away just enough to solve the problem or solve the harder problem in the hoping of reusing that code to make life easier in the future?
I'd say, unless you are developing a general-purpose library, solve the problem in the simplest (correct!) way first. One of the nice things about Haskell is that its easy to replace code under the hood at a later time (pure functional programming is your friend). For example if you write:
areaOfSquare :: Square -> Double areaOfSquare = <special purpose code>
And later you discover you also need:
areaOfNPolygon :: NPolygon -> Double areaOfNPolygon = <n-polygon code>
You can replace areaOfSquare with:
areaOfSquare = areaOfNPolygon . squareToNPolygon
to reduce duplication, or you can keep the special-purpose code in the interests of efficiency. If you keep the special-purpose code, you can use quick check to make sure it gives the same answer as the n-polygon routine, which is a nice benefit. Rob Dockins Speak softly and drive a Sherman tank. Laugh hard; it's a long way to the bank. -- TMBG