获取错误Prelude.read:没有解析

时间:2011-11-13 08:49:58

标签: haskell

sample input/output

我是haskell的新手,我编写了项目详细信息的代码并搜索每个项目的详细信息。

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

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

搜索代码

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)

但是,问题是,它对单个数据有效,如果我追加另一个数据,那么当我尝试搜索该项时它会显示错误Prelude.read: no parse。 帮助将不胜感激!!

1 个答案:

答案 0 :(得分:4)

您的问题是数据文件的格式。使用textfile后,该文件包含以下内容:

[(110,"B")]

这是一个很好的清单,它有效。第二次使用textfile后,该文件包含以下内容:

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

这不是一个好的清单,它失败了。您可以在ghci

中看到这一点
*Main> read "[(110,\"B\")][(110,\"B\")]" :: [Database]
*** Exception: Prelude.read: no parse

很明显,read需要一个列表,而不是两个列表。

如果要附加到包含单个Haskell列表的文件,则需要读取该文件,附加到列表中,并将新列表作为替换文件写入文件中。

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

由于有两种情况,这有点棘手:

  • readFile是懒惰的,同一文件的writeFile可能会失败,除非确保已经读取了整个文件。在上面的函数中,这是通过在写入文件之前询问新字符串的长度来解决的(seq函数确保在写入操作发生之前计算长度。)
  • 该文件可能不存在,上面使用catch子句来处理该异常情况。