[Haskell-beginners] Need help with code duplication (types and typeclasses)

Edward Turpin eturpin at live.com
Sat Oct 23 23:24:05 EDT 2010


I can't seem to get my head around types and typeclasses (as well as
many other things in Haskell).  Here's the following code I need help
with.

In module 1:
//////////////////////// Start of Code //////////////////////////////
data NewtonRow = NewtonRow { iteration :: Integer,
                             xn :: Double,
                             fxn :: Double,
                             errEst :: Double
                           }

instance Show NewtonRow where
    show row = show (iteration row) ++ "\t" ++
               showEFloat (Just 8) (xn row) "\t" ++
               showEFloat (Just 2) (fxn row) "\t" ++
               showEFloat (Just 2) (errEst row) "\n"

newtype NewtonTable = NewtonTable { getNewtonTable :: [NewtonRow] }

instance Show NewtonTable where
    show table = "n\t" ++ "xn\t\t\t" ++ "fxn\t\t" ++ "xn - xn-1\n" ++
                 concatMap show (getNewtonTable table)

instance Monoid NewtonTable where
    mempty = NewtonTable []
    table1 `mappend` table2 = NewtonTable $ (getNewtonTable table1) ++
(getNewtonTable table2)

cons :: NewtonRow -> NewtonTable -> NewtonTable
row `cons` table = NewtonTable (row : getNewtonTable table)
//////////////////////  End of Code  ////////////////////////////////
In module 2:
/////////////////  Start of more Code ///////////////////////////////
data BisectRow = BisectRow { iteration :: Integer,
                             start :: Double,
                             end :: Double,
                             middle :: Double,
                             deviation :: Double,
                             fm :: Double
                           }

instance Show BisectRow where
    show row = show (iteration row) ++ "\t" ++
               showEFloat (Just 4) (start row) "\t" ++
               showEFloat (Just 4) (end row) "\t" ++
               showEFloat (Just 4) (middle row) "\t" ++
               showEFloat (Just 4) (deviation row) "\t" ++
               showEFloat (Just 4) (fm row) "\n"

newtype BisectTable = BisectTable { getBisectTable :: [BisectRow] }

instance Show BisectTable where
    show table = "n\t" ++ "start\t\t" ++ "end\t\t" ++ "middle\t" ++
"error\t\t" ++ "f(middle)\n" ++
                 concatMap show (getBisectTable table)

instance Monoid BisectTable where
    mempty = BisectTable []
    table1 `mappend` table2 = BisectTable $ (getBisectTable table1) ++
(getBisectTable table2)

cons :: BisectRow -> BisectTable -> BisectTable
row `cons` table = BisectTable (row : getBisectTable table)
////////////////////// End of code /////////////////////////////////

There is obviously duplication going on, but I can't figure out how to
get rid of it.  "BisectTable" is essentially the same as "NewtonTable"
except that it has a different number of columns, different column
headers (in the "show" functions), and different row elements.
"BisectRow" and "NewtonRow" are also somewhat similar.  And the "cons"
functions in each module pretty much do the same thing.  I'm just trying
to learn Haskell, so as far as I know I might be doing ass-backwards.
Can anybody give any suggestions?



More information about the Beginners mailing list