如何创建从文件中读取一行的程序,将其解析为int并打印它(当然忽略异常)。是否有类似"阅读"但对于 IO String ?
到目前为止,我已经解决了这个问题,但我无法绕过 IO 类型:
readFromFile = do
inputFile <- openFile "catalogue.txt" ReadMode
isbn <- read( hGetLine inputFile)
hClose inputFile
答案 0 :(得分:2)
您可以明确指定类型,将读取行更改为
isbn <- fmap read (hGetLine inputFile) :: IO Int
由于hGetLine inputFile
属于IO String
类型,您应使用fmap
将“内部”视为Int
。
答案 1 :(得分:1)
您可以使用readFile
功能将文件转换为字符串。
main = do
contents <- readFile "theFile"
let value = read $ head $ lines contents::Int
print value
您应该添加更好的错误检测,否则如果没有第一行,或者该值格式错误,此程序将失败,但这是基本流程....
答案 2 :(得分:0)
首先,观察读取内容然后立即打印它可能会导致神秘的错误:
GHCi, version 8.0.0.20160421: http://www.haskell.org/ghc/ :? for help
Prelude λ read "123"
*** Exception: Prelude.read: no parse
原因是您没有指定要阅读的类型。您可以使用类型注释来解决此问题:
Prelude λ read "123" :: Integer
123
但有时候引入一个小帮助函数会更容易:
Prelude λ let readInteger = read :: String -> Integer
Prelude λ readInteger "123"
123
现在到了主要问题。 read( hGetLine inputFile)
无法正常工作,因为hGetLine inputFile
返回,而IO String
和read
需要String
。这可以通过两个步骤解决:
line <- hGetLine inputFile
let isbn = readInteger line
注意两个不同的结构<-
和let .. =
,它们做不同的事情。你能弄明白到底是什么吗?
如另一个答案所示,你可以用一种不那么冗长的方式来做:
isbn&lt; - fmap readInteger(hGetLine inputFile)
如果您执行read
之类的简单操作,那就太棒了。但通常需要明确命名中间结果。在这种情况下,您可以使用<-
和let .. =
构造。