[英]Haskell IO Function -> Type Match Error
I am developing a function which reads user input of the form "a 2" and then converts it into a tuple and adds it to a list of tuples. 我正在开发一个函数,它读取“a 2”形式的用户输入,然后将其转换为元组并将其添加到元组列表中。 This is supposed to keep happening until the user types in "done".
这应该继续发生,直到用户键入“完成”。
The code is as follows... 代码如下......
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))
How ever, when trying to execute this file, I get the error 但是,在尝试执行此文件时,我收到错误
> ERROR file:.\MainApp.hs:13 - Type error in final generator
*** Term : getVectorData vector1
*** Type : IO ()
*** Does not match : [a]
What am I doing wrong? 我究竟做错了什么?
You are mixing IO
with pure non- IO
functions. 您正在将
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"
The above is all IO
以上都是
IO
else do
createVectorTuple (words appData) : vector1
createVectorTuple
is a non- IO
function. createVectorTuple
是一个非IO
函数。 Since the preceding part is an IO
do-block, only expressions of type IO a
may appear in that do-block. 由于前一部分是
IO
do-block,因此只有类型IO a
表达式可能出现在do-block中。 However, you get the somewhat strange error message because the precedence of function application is highest, so the above line is parsed 但是,您会收到一些奇怪的错误消息,因为函数应用程序的优先级最高,因此解析了上面的行
(createVectorTuple (words appData)) : vector1
which is an expression of type [(String, Float)]
(if vector1
has that type). 这是
[(String, Float)]
类型的表达式(如果vector1
具有该类型)。 Now []
is a monad too, so expressions of type [a]
can appear in do-blocks, but then all expressions in that block must have list type. 现在
[]
也是一个monad,因此类型[a]
表达式可以出现在do-blocks中,但是那个块中的所有表达式都必须具有列表类型。 But 但
getVectorData vector1
is an expression of type IO ()
as has been determined from the part above. 是从上面的部分确定的
IO ()
类型的表达式。 Thus the types don't match. 因此类型不匹配。 Admittedly, the reported type error is not the clearest possible in that situation.
不可否认,在这种情况下,报告的类型错误并不是最明显的。
You probably want something along the lines of 你可能想要一些东西
let vector2 = createVectorTuple (words appData) : vector1
getVectorData vector2
or something completely different, I can't tell from the short snippet. 或者完全不同的东西,从简短的片段我无法分辨。
Its a bit difficult to tell, but "createVectorTuple is not of type "IO ()", so this is probably the real problem. "do" clauses can have many different types, so the type inference is probably making a wrong guess based on "createVectorTuple", and then the error message is because the next line doesn't match its guess. 它有点难以辨别,但“createVectorTuple不是类型”IO()“,所以这可能是真正的问题。”do“子句可以有许多不同的类型,因此类型推断可能是基于错误猜测“createVectorTuple”,然后错误消息是因为下一行与其猜测不匹配。
What you probably want to say is 你可能想说的是
else
getVectorData $ createVectorTuple (words appData) : vector1
Did you want: 你想要的是:
else do
let vector1 = createVectorTuple (words appData)
getVectorData vector1
You will also have to return
something after the putStrLn "That's it." 你还必须在putStrLn之后
return
一些东西“就是这样”。 so both branches of the if have the same type. 所以if的两个分支都有相同的类型。 Something like:
就像是:
if appData == "done" then do
putStrLn "That's it"
return vector1
else getVectorData (createVectorTuple (words appData) : vector1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.