question regarding ordering of function definitions

Hello all! I've just started learning (and using haskell), and am also using the literate comment mode (latex style), and just ran into a problem that seems like it ought to have a simple solution, which is that it seems that haskell requires you to define all the variations of a function sequentially, which is raining on my literate programming parade. Here is what I'd like to do: \begin{code} data D = A String | B String instance Show D where show = showD instance Read D where readsPrec _ = readsD readD s = (readsA s) ++ (readsB s) \end{code} A is formatted like ``A string''. \begin{code} showD (A s) = "A " ++ s readsA s = [(A thestr, r) | ("A", x) <- mylex s, (thestr, r) <- mylex x] \end{code} B is formatted like ``B string''. \begin{code} showD (B s) = "B " ++ s readsB s = [(B thestr, r) | ("B", x) <- mylex s, (thestr, r) <- mylex x] \end{code} The problem I have is that ghc complains because I've split up the definition of showD with readsA defined in between. This surprised me, since it seemed that the code should still be unambiguous. Is there some nice way around this, or do I have to define a separate function for each constructor, and then have a list in one place (as I do with the readsD, in that case because pattern matching won't give me what I want), like: showD (A s) = showA (A s) showD (B s) = showB (B s) Of course, in my actual example, there are more than two constructors, and the parsing is considerably more complex, which is why I'd like to put the analagous showing and parsing right next to eachother along with a description of what the formatting is intended to be. -- David Roundy http://civet.berkeley.edu/droundy/

David Roundy wrote (on 21-09-02 07:30 -0400):
Here is what I'd like to do:
\begin{code} data D = A String | B String instance Show D where show = showD instance Read D where readsPrec _ = readsD readD s = (readsA s) ++ (readsB s) \end{code}
A is formatted like ``A string''. \begin{code} showD (A s) = "A " ++ s readsA s = [(A thestr, r) | ("A", x) <- mylex s, (thestr, r) <- mylex x] \end{code} .. [ and similarly for B ] ...
The problem I have is that ghc complains because I've split up the definition of showD with readsA defined in between. This surprised me, since it seemed that the code should still be unambiguous.
Is there some nice way around this,
There's no way to intersperse clauses of top-level declarations, no.
or do I have to define a separate function for each constructor, and then have a list in one place (as I do with the readsD, in that case because pattern matching won't give me what I want), like:
showD (A s) = showA (A s) showD (B s) = showB (B s)
Almost. But then showA and showB are partial. It's better to do this: showA s = "A " ++ s and similarly for B, and then: data D = A String | B String instance Show D where show (A s) = showA s show (B s) = showB s instance Read D where readsPrec _ = readsD readD s = (readsA s) ++ (readsB s) What you are doing here basically is just assigning names to the branches of a case-expression: h sum = case sum of Left x -> ... x ... Right y -> ... y ... <= h sum = case sum of Left x -> (\x' -> ... x' ...) x Right y -> (\y' -> ... y' ...) y <= h sum = let f x' = ... x' ... g y' = ... y' ... in case sum of Left x -> f x Right y -> g y <= f x' = ... x' ... g y' = ... y' ... h (Left x) = f x h (Right y) = g y -- Frank

On Sat, Sep 21, 2002 at 02:55:24PM +0200, Frank Atanassow wrote:
Almost. But then showA and showB are partial. It's better to do this:
showA s = "A " ++ s
and similarly for B, and then:
data D = A String | B String instance Show D where show (A s) = showA s show (B s) = showB s instance Read D where readsPrec _ = readsD readD s = (readsA s) ++ (readsB s)
Thank you for this advice! This solved my quandry quite cleanly. -- David Roundy http://civet.berkeley.edu/droundy/
participants (3)
-
David Roundy
-
David Roundy
-
Frank Atanassow