简体   繁体   English

Haskell IO函数 - >类型匹配错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM