Reputation:
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
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).catch
clause is used above to handle that exceptional case.Upvotes: 4