例如,我想读取一个只包含整数的文件,并在函数中对这些整数执行某些操作:
getIntFromFile :: () -> Int
getIntFromFile _ = do
h <- openFile "/tmp/file" ReadMode
str <- hGetLine h
let x = read str :: Int
str <- hGetLine h
let y = read str :: Int
hClose h
x + y
当我将包含此函数的文件加载到ghci时,我得到了输出
Prelude System.IO> :l graphBat.hs
[1 of 1] Compiling Plugins.GraphBat ( graphBat.hs, interpreted )
graphBat.hs:77:22:
Couldn't match type ‘IO b0’ with ‘() -> Int’
Expected type: IO Handle -> (Handle -> IO b0) -> () -> Int
Actual type: IO Handle -> (Handle -> IO b0) -> IO b0
In a stmt of a 'do' block: h <- openFile "/tmp/file" ReadMode
In the expression:
do { h <- openFile "/tmp/file" ReadMode;
str <- hGetLine h;
let x = ...;
str <- hGetLine h;
.... }
In an equation for ‘getIntFromFile’:
getIntFromFile
= do { h <- openFile "/tmp/file" ReadMode;
str <- hGetLine h;
let x = ...;
.... }
graphBat.hs:85:22:
Couldn't match expected type ‘IO b0’ with actual type ‘Int’
In the first argument of ‘(+)’, namely ‘x’
In a stmt of a 'do' block: x + y
graphBat.hs:85:26:
Couldn't match expected type ‘IO b0’ with actual type ‘Int’
In the second argument of ‘(+)’, namely ‘y’
In a stmt of a 'do' block: x + y
Failed, modules loaded: none.
我做错了什么?我应该如何编写一个读取文件的典型函数,处理该文件并返回此处理的结果?
答案 0 :(得分:6)
如果你做IO,你必须在IO monad中工作:
getIntFromFile :: () -> IO Int -- Added IO here
getIntFromFile _ = do
h <- openFile "/tmp/file" ReadMode
str <- hGetLine h
let x = read str :: Int
str <- hGetLine h
let y = read str :: Int
hClose h
return (x + y) -- Added return
您也可以删除()
参数并以:
getIntFromFile :: IO Int -- Added IO here
getIntFromFile = do
...
事实上,使用() -> ...
是Haskell中的反模式。