read int lists

Serge D. Mechveliani mechvel@botik.ru
Tue, 30 Apr 2002 18:00:27 +0400


Dear Haskellers,

There is certain site (contact  daly@idsi.net ) 

where some computer algebra programs are gathered and compared.
I submit here my CA program DoCon written in Haskell.
And they require certain large set of tests to fill in.
It appears also that many of the tests concern Haskell itself
(or its implementation libraries) rather than DoCon library.
In particular, they require the code for the task:
 
  Import two space separated columns of integers from file.

The suggestions are:
  \Axiom       & \\
  \Derive      & [Transfer Load daTa]  (from file.dat)        
  \Macsyma     & xy: read_num_data_to_matrix("file", nrows, 2)
  \Maple       & xy:= readdata("file", integer, 2): 
  \Mathematica & xy = ReadList["file", Number, RecordLists -> True]
  \MuPAD       & \\
  \Reduce      & \\
  \DoCon (Haskell) &  ??


We need   main = readFile "data" >>= (putStr . process)

If it was one integer list, then, something like

  process str = read ("[" ++ (map (\ '\n' -> ',') str) ++ "]") 
                                                  :: [Integer]
would do.
But the file contains something like
-----------


1
2


3
4


-----------
, and it should convert to  ([1,2],[3,4]) :: ([Integer], [Integer])
 
Although I wonder whether other systems do the needed thing,
still, can people suggest any shorter/nicer program than the 
following one?
(use advanced lexical libraries, etc. ...)

  process :: String -> String
  process str = shows (firstList [] $ dropWhile (== '\n') $
                       filter (/= ' ') str
                      ) "\n"
  firstList :: [Integer] -> String -> ([Integer], [Integer])

  firstList ns ('\n':'\n':str) = (reverse ns, secondList str)
  firstList ns str             = case  reads str :: [(Integer, String)]
                                 of
                                   [(n,str')] -> firstList (n:ns) str'
                                   _          -> (ns, [])
  secondList :: String -> [Integer]
  secondList str = case  reads str :: [(Integer, String)]
                   of
                     [(n,str')] -> n:(secondList str')
                     _          -> []


Thank you in advance for the help.

-----------------
Serge Mechveliani
mechvel@botik.ru