如何创建一个程序从文件中读取一行,将其解析为一个int并将其打印(忽略当然的例外)。有什么像“读”但IO字符串?Haskell - 从一个文件读取一个int并打印它
我有这到目前为止,但我不能围绕IO类型得到:
readFromFile = do
inputFile <- openFile "catalogue.txt" ReadMode
isbn <- read(hGetLine inputFile)
hClose inputFile
如何创建一个程序从文件中读取一行,将其解析为一个int并将其打印(忽略当然的例外)。有什么像“读”但IO字符串?Haskell - 从一个文件读取一个int并打印它
我有这到目前为止,但我不能围绕IO类型得到:
readFromFile = do
inputFile <- openFile "catalogue.txt" ReadMode
isbn <- read(hGetLine inputFile)
hClose inputFile
首先,观察,阅读的东西,然后立即打印出来可能会导致奇怪的错误:
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 < - FMAP readInteger(hGetLine INPUTFILE)
如果你做一个简单的事情,像read
这是伟大的。但通常需要明确命名中间结果。在这种情况下,您可以使用<-
和let .. =
构造。
可以使用readFile
功能将文件转换为字符串。
main = do
contents <- readFile "theFile"
let value = read $ head $ lines contents::Int
print value
您应该添加更好的错误检测,或者如果没有第一线,或者如果该值是畸形的,但是这是基本流程这一计划将失败....
为什么Int值是Int而不是IO Int? –
在Haskell的符号中,'<-'左边的值实际上是带有monad(在本例中为IO)的项目类型。所以虽然'readFile'行的类型为'IO String',但在下一行中,value只有'String'类型。 – jamshidh
所以像“value < - value”这样的东西也会删除IO呢? –
你可以明确指定类型,更改读取行
isbn <- fmap read (hGetLine inputFile) :: IO Int
由于hGetLine inputFile
是IO String
类型的,你应该使用fmap
得到“内部”读为Int
。
不是那么快!还有人仍然在ghc 6上! –
fmap实际上做了什么? –
@EricMarchettiSantos它将一个简单的函数'a - > b'作为'IO a - > IO b'在IO下工作(它也适用于其他函子)。 – chi
这对我来说还是有点阴。 readInteger是String - > Int,因此“let .. =”将以某种方式将其更改为IO String - > IO Integer。那是对的吗? –
不完全。 'hGetLine inputFile'是'IO String',但是当你说'line < - hGetLine inputFile'时,'line'就是'String'。那么'let .. ='也不会添加任何IO。你*将*必须在'do'块的最后一行返回到IO,例如,使用'print isbn'(这会返回'IO()')。 –
在'line < - hGetLine inputFile'中,'< - '将'IO String'转换为'String'? –