Haskell - 从文件中读取单个int并打印它

时间:2016-05-31 16:49:20

标签: haskell

如何创建从文件中读取一行的程序,将其解析为int并打印它(当然忽略异常)。是否有类似"阅读"但对于 IO String

到目前为止,我已经解决了这个问题,但我无法绕过 IO 类型:

readFromFile = do
   inputFile <- openFile "catalogue.txt" ReadMode

   isbn <- read( hGetLine inputFile)


   hClose inputFile

3 个答案:

答案 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 Stringread需要String。这可以通过两个步骤解决:

line <- hGetLine inputFile
let isbn = readInteger line

注意两个不同的结构<-let .. =,它们做不同的事情。你能弄明白到底是什么吗?

如另一个答案所示,你可以用一种不那么冗长的方式来做:

isbn&lt; - fmap readInteger(hGetLine inputFile)

如果您执行read之类的简单操作,那就太棒了。但通常需要明确命名中间结果。在这种情况下,您可以使用<-let .. =构造。