Haskell IO功能 - >键入匹配错误

时间:2012-01-25 18:08:09

标签: haskell io

我正在开发一个函数,它读取“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]

我做错了什么?

4 个答案:

答案 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)