5 haskell

我是haskell的新手,我为项目详细信息编写代码并搜索每个项目的详细信息.
type Code = Int
type Name = String
type Database = (Code,Name)
textfile::IO()
textfile = appendFile "base.txt" (show[(110,"B")])
Run Code Online (Sandbox Code Playgroud)
搜索代码
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)
Run Code Online (Sandbox Code Playgroud)
但是,问题是,它对单个数据有效,如果我追加另一个数据,那么Prelude.read: no parse当我尝试搜索该项时它会显示错误.帮助将不胜感激!
您的问题出在数据文件的格式上。使用一次后textfile,该文件包含以下内容:
[(110,"B")]
Run Code Online (Sandbox Code Playgroud)
这是一个很好的清单,而且很有效。第二次使用后textfile,该文件包含以下内容:
[(110,"B")][(110,"B")]
Run Code Online (Sandbox Code Playgroud)
这不是一个好的清单,而且失败了。您可以在以下位置看到这一点ghci:
*Main> read "[(110,\"B\")][(110,\"B\")]" :: [Database]
*** Exception: Prelude.read: no parse
Run Code Online (Sandbox Code Playgroud)
很明显,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
Run Code Online (Sandbox Code Playgroud)
由于两个问题,这有点棘手:
readFile是惰性的,除非writeFile确保整个文件已被读取,否则对同一个文件可能会失败。在上面的函数中,这是通过在写入文件之前询问新字符串的长度来解决的(该seq函数确保在写入操作发生之前计算长度)。catch上面使用该子句来处理这种异常情况。| 归档时间: |
|
| 查看次数: |
9478 次 |
| 最近记录: |