user918477
user918477

Reputation:

getting error Prelude.read: no parse

sample input/output

I am very new in haskell, i wrote the code for item details and search the detail for each item.

type Code = Int
type Name = String 
type Database = (Code,Name)

textfile::IO()
textfile = appendFile "base.txt" (show[(110,"B")])

code for search

fun::IO ()
fun=do putStrLn"Please enter the code of the product"
       x<-getLine
       let y = read x :: Int
       show1 y 

textshow::IO [Database]
textshow= do x<-readFile "base.txt"
             let y=read x::[Database]
         return y

show1::Code->IO ()
show1 cd= do o<-textshow
             let d=[(x,y)|(x,y)<-o,cd==x]
         putStr(show d)

but, the problem is, it is working good for single data, if i append another data, then it showing error Prelude.read: no parse when i am trying to search the item. Help will be appreciated !!

Upvotes: 5

Views: 11079

Answers (1)

ibid
ibid

Reputation: 3902

Your problem is in the format of your data file. After one use of textfile, the file contains the following:

[(110,"B")]

That's a good list, and it works. After the second use of textfile, the file contains the following:

[(110,"B")][(110,"B")]

That's not a good list, and it fails. You can see this in ghci:

*Main> read "[(110,\"B\")][(110,\"B\")]" :: [Database]
*** Exception: Prelude.read: no parse

It's clear that read expects a single list, not two lists following each other.

If you want to append to a file that contains a single Haskell list, you need to read the file, append to the list, and write the new list in the file as a replacement.

addToFileList :: (Read a, Show a) => FilePath -> a -> IO ()
addToFileList fp a = do olds <- readFile fp `catch` \e ->
                                if isDoesNotExistError e 
                                then return "[]"
                                else ioError e
                        let oldl = read olds
                            newl = oldl ++ [a]
                            news = show newl
                        length news `seq`
                               writeFile fp news

This is a little tricky because of two tings:

  • readFile is lazy, and writeFile to the same file can fail unless one makes sure that the whole file has already been read. In the function above this is solved by asking for the length of the new string before writing the file (the seq function makes sure that the length is computed before the write operation happens).
  • the file may not exist, the catch clause is used above to handle that exceptional case.

Upvotes: 4

Related Questions