【问题标题】:Haskell issue (Couldn't match type 'IO Integer' with 'Int')Haskell 问题(无法将类型“IO Integer”与“Int”匹配)
【发布时间】:2015-02-17 19:57:55
【问题描述】:

我的 Haskell 脚本有问题。我正在尝试通过解决我在网上找到的问题来学习 Haskell。我得到的输入是: Int -> 测试用例数 S1 -> 每个测试用例的字符串 1 S2 -> 每个测试用例的字符串 2

每个 S1 和 S2 都是一个以空格分隔的数字串。我使用函数strToIntList 将它们转换为整数列表。然后我想处理这两个列表并根据结果返回一个整数值。我收到以下错误:Couldn't match type 'IO Integer' with 'Int' 在第 24 行,我盯着看了很长时间,但就是不知道为什么(帖子末尾的完整错误)。

如果有人能解释我为什么会出错,我将非常感激。

这是我的脚本:

import Data.List
import Data.List.Split

main = do
    cases <- readLn
    doLoop cases

toInt x = read x :: Int

strToIntList s = [read x :: Int | x <- (splitOn " " s)]

minOfTwo :: Int
minOfTwo = do
    sa <- getLine
    sb <- getLine
    return $ minimum [1..50]
    -- return $ minimum $ strToIntList sa

doLoop 0 = return ()
doLoop loopIndex = do
    q <- getLine
    let c = minOfTwo
    print(c)
    doLoop (loopIndex-1)

这是我得到的完整错误:

Couldn't match type `IO Integer' with `Int'
Expected type: IO String -> (String -> IO Integer) -> Int
  Actual type: IO String -> (String -> IO Integer) -> IO Integer
In a stmt of a 'do' block: sa <- getLine
In the expression:
  do { sa <- getLine;
       sb <- getLine;
       return $ minimum [1 .. 50] }
In an equation for `minOfTwo':
    minOfTwo
      = do { sa <- getLine;
             sb <- getLine;
             return $ minimum [1 .. 50] }

【问题讨论】:

  • 你的minOfTwo函数必须有一个IO类型,如果它有IO,把它改成minOfTwo :: IO Int
  • 附带说明,您最好使用来自Text.ReadreadMaybe 而不是read,因为如果解析失败而不是崩溃,它将返回Nothing程序。这确实意味着您必须编写更多代码来处理它,但是编写更多代码来进行正确的错误处理通常被认为是一件好事。不过,对于快速一次性脚本,可以使用 read 这样的不安全函数。
  • 谢谢你。因为这是一个学习练习,并且输入保证是正确的,所以我还不太担心输入验证。

标签: haskell


【解决方案1】:

getLine 函数在 IO monad 中,因此任何调用 getLine 的函数也必须在 IO monad 中。将minOfTwo 的类型签名从Int 更改为IO Int,这个特定问题就会消失。

(您还需要将let c = minOfTwo 更改为c &lt;- minOfTwo。)

可能还有其他错误,但这是导致您的错误消息的原因。

【讨论】:

  • 谢谢!这是因为当一个函数使用 IO 时,不能保证每次使用相同的参数调用它的结果都是相同的?
猜你喜欢
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 1970-01-01
  • 2014-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多