我正在开发一个函数,它读取“a 2”形式的用户输入,然后将其转换为元组并将其添加到元组列表中。这应该继续发生,直到用户键入“完成”。
代码如下......
getVectorData vector1 = do
putStrLn "Enter dimension and coefficient separated by a space: Enter \"Done\" to move on to next vector: "
appData <- getLine
if appData == "done" then
putStrLn "That's it"
else do
createVectorTuple (words appData) : vector1
getVectorData vector1
createVectorTuple :: [String] -> (String, Float)
createVectorTuple vectorData = ((head vectorData) , (read (last vectorData) :: Float))
然而,当尝试执行此文件时,我收到错误
> ERROR file:.\MainApp.hs:13 - Type error in final generator
*** Term : getVectorData vector1
*** Type : IO ()
*** Does not match : [a]
我做错了什么?
答案 0 :(得分:4)
您正在将IO
与纯非IO
函数混合使用。
getVectorData vector1 = do
putStrLn "Enter dimension and coefficient separated by a space: Enter \"Done\" to move on to next vector: "
appData <- getLine
if appData == "done" then
putStrLn "That's it"
以上都是IO
else do
createVectorTuple (words appData) : vector1
createVectorTuple
是非IO
函数。由于前一部分是IO
do-block,因此只有IO a
类型的表达式可能出现在do-block中。但是,您会收到一些奇怪的错误消息,因为函数应用程序的优先级最高,因此上面的行被解析
(createVectorTuple (words appData)) : vector1
是[(String, Float)]
类型的表达式(如果vector1
具有该类型)。现在[]
也是monad,因此类型[a]
的表达式可以出现在do-blocks中,但是那个块中的所有表达式都必须具有列表类型。但
getVectorData vector1
是类型IO ()
的表达式,如上面部分所确定的。因此类型不匹配。不可否认,在这种情况下,报告的类型错误并不是最明显的。
你可能想要一些
的内容let vector2 = createVectorTuple (words appData) : vector1
getVectorData vector2
或完全不同的东西,我从简短的片段中无法分辨。
答案 1 :(得分:2)
它有点难以辨别,但“createVectorTuple不是类型”IO()“,所以这可能是真正的问题。”do“子句可以有许多不同的类型,因此类型推断可能是错误的根据“createVectorTuple”猜测,然后错误信息是因为下一行与其猜测不匹配。
你可能想说的是
else
getVectorData $ createVectorTuple (words appData) : vector1
答案 2 :(得分:0)
你想要:
else do
let vector1 = createVectorTuple (words appData)
getVectorData vector1
答案 3 :(得分:0)
在putStrLn“你就是这样”之后你还需要return
。所以if的两个分支都有相同的类型。类似的东西:
if appData == "done" then do
putStrLn "That's it"
return vector1
else getVectorData (createVectorTuple (words appData) : vector1)