【问题标题】:Haskell IO Function -> Type Match ErrorHaskell IO 函数 -> 类型匹配错误
【发布时间】:2012-01-26 09:33:23
【问题描述】:

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

我做错了什么?

【问题讨论】:

  • 附带说明,createVectorTuple 函数运行良好。

标签: haskell io


【解决方案1】:

您将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 块中,但是该块中的所有表达式都必须具有列表类型。但是

        getVectorData vector1

是一个IO () 类型的表达式,正如上面部分所确定的。因此类型不匹配。诚然,在这种情况下,报告的类型错误并不是最清楚的。

你可能想要一些类似的东西

let vector2 = createVectorTuple (words appData) : vector1
getVectorData vector2

或完全不同的东西,我无法从简短的 sn-p 中分辨出来。

【讨论】:

    【解决方案2】:

    有点难说,但是“createVectorTuple 不是类型“IO ()”,所以这可能是真正的问题。“do”子句可以有很多不同的类型,所以类型推断可能是错误的根据“createVectorTuple”猜测,然后错误信息是因为下一行不匹配它的猜测。

    你可能想说的是

    else
       getVectorData $ createVectorTuple (words appData) : vector1
    

    【讨论】:

      【解决方案3】:

      你想要吗:

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

      【讨论】:

        【解决方案4】:

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

        if appData == "done" then do
               putStrLn "That's it"
               return vector1
            else getVectorData (createVectorTuple (words appData) : vector1)
        

        【讨论】:

          猜你喜欢
          • 2013-05-04
          • 1970-01-01
          • 2021-03-24
          • 2014-10-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多