繁体   English   中英

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

[英]Haskell IO Function -> Type Match Error

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

我究竟做错了什么?

您正在将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

或者完全不同的东西,从简短的片段我无法分辨。

它有点难以辨别,但“createVectorTuple不是类型”IO()“,所以这可能是真正的问题。”do“子句可以有许多不同的类型,因此类型推断可能是基于错误猜测“createVectorTuple”,然后错误消息是因为下一行与其猜测不匹配。

你可能想说的是

else
   getVectorData $ createVectorTuple (words appData) : vector1

你想要的是:

else do
    let vector1 = createVectorTuple (words appData)
    getVectorData vector1

你还必须在putStrLn之后return一些东西“就是这样”。 所以if的两个分支都有相同的类型。 就像是:

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