[Haskell-beginners] Prelude.(!!): index too large

Roger Mason rmason at mun.ca
Thu Apr 4 20:47:41 CEST 2013


Hello,

Thanks for the response
On 04/04/2013 03:54 PM, David McBride wrote:
> It just means you are trying to directly access a list element by its 
> index in a list that doesn't have that many elements.  It is probably 
> somewhere in your floatData function, which you did not list.  When 
> you don't print it out to screen, haskell does not bother to evaluate 
> it and therefore it never hits that error.  If you didn't use that 
> operator, then it is used in some library you are using.
>
I cleaned up the code layout and the error has now been replaced by another:

f: <<loop>>

The complete code (below) is pretty ugly.  If anyone has a few minutes 
to look it over and suggest a source for the error that would be very 
helpful.

Thanks,
Roger

import System.Environment       -- For command line args
import System.IO                -- For, er, IO
import System.Exit              -- For early parole

main = do
        cmdLineArgs              -- Check only
        args <- getArgs
        let consts = args !! 1
        let list = []
        loadFile consts list   -- Read file containing mol wts etc into 
'list'
        let analytes = head list -- Names of analysed components (oxid, 
element...)
        let mw       = floatData ( (processData list) !! 1 ) -- Weight 
(amu) of analyte
        let nox      = floatData ( (processData list) !! 2 ) -- Oxygens 
in oxide formula
        let ncat     = floatData ( (processData list) !! 3 ) -- Cations 
in oxide formula
        let units    = floatData ( (processData list) !! 4 ) -- 1 = wt%; 
1E4 = ppm
        let list = []
        let fox = read (args !! 0) :: Float -- number of oxygens in f.u.
        let analyses = args !! 2
        let outfile  = args !! 3
        loadFile analyses list  -- Read file containing analyses into 'list'
        writeOutput analyses outfile list fox mw nox ncat units -- Write 
recalculated formulae into outfile
        mapM_ putStrLn list

loadFile consts list = do
     inh <- openFile consts ReadMode
     list <- hGetContents inh
     hClose inh

writeOutput infile outfile list fox mw nox ncat units = do
           inh <- openFile infile ReadMode -- the file of analyses, one 
per line
           outh <- openFile outfile WriteMode
           mainloop inh outh list fox mw nox ncat units
           hClose outh
           hClose inh

-- the calculations are here
mainloop inh outh list fox mw nox ncat units = do
              ineof <- hIsEOF inh
              if ineof
                      then do
                          print list      -- For testing/debugging only
                          return ()
                          else do
                              inpStr <- hGetLine inh
                              let list' = inpStr:list
                                  dat = floatData list' -- the 
analytical input data
                                  ta = zipWith (/) dat 
units                            -- convert all to wt%
                                  moles = zipWith (/) ta mw
                                  apo = zipWith (*) nox moles
                                  factor = fox/(sum apo)
                                  nanions= (map (* factor) apo)
                                  catox = zipWith (/) ncat nox
                                  ncat = zipWith (*) catox nanions
                              hPutStr outh ( show ncat)
                              mainloop inh outh list' fox mw nox ncat units


cmdLineArgs = do
    args <- getArgs
    usage (length args)                  -- check 'em

usage :: Int -> IO ()
usage nargs
       | nargs < 4 = fallOverAndDie "Usage: formula 'ox in formula' 'mol 
wt. file' 'analysis file' 'output file'."
       | otherwise = putStrLn "Input looks OK"

fallOverAndDie :: String -> IO a
fallOverAndDie err = do putStrLn err
                         exitWith (ExitFailure 1)

-- Convert the input numbers from strings to floats
floatData :: [String] -> [Float]
floatData inList = map read inList::[Float]

-- Split input file into lines & words
processData :: String -> [[String]]
processData inpStr = do
             let thelines = lines inpStr
             let thewords = map words thelines
             thewords

This is how I built the executable:

ghc --make f.hs
ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.6.1


This electronic communication is governed by the terms and conditions at
http://www.mun.ca/cc/policies/electronic_communications_disclaimer_2012.php



More information about the Beginners mailing list