我是Haskell的初学者,对我编写的代码感到困惑
readRecords :: String -> [Either String Record]
readRecords path = do
f <- B.readFile path
map parseLogLine (C8.lines f)
但它给了我这个错误:
Main.hs:15:10:
Couldn't match type `IO' with `[]'
Expected type: [C8.ByteString]
Actual type: IO C8.ByteString
In the return type of a call of `B.readFile'
In a stmt of a 'do' block: f <- B.readFile path
In the expression:
do { f <- B.readFile path;
map parseLogLine (C8.lines f) }
parseLogLine
的类型签名为parseLogLine :: B8.ByteString -> Either String Record
。
我完全惊讶。 B.readFile path
应该返回IO ByteString
,因此f
应该是ByteString
。 C8.lines f
应该返回[ByteString]
,地图应该return [Either String Record]
。
我哪里错了?
答案 0 :(得分:7)
作为起点,readRecords
的定义类型错误。如果do
块在IO
monad中工作,那么它将生成IO
值,但您已将其定义为返回[Either String Record]
[]
{1}} monad。这意味着您无法在不触发类型错误的情况下调用返回B.readFile
的{{1}}。
修复后,您会发现do块最后一行的IO
表达式类型错误,因为它生成map
时会生成[Either String Record]
。在IO [Either String Record]
中换取呼叫以解决此问题。