0

我正在尝试为我用 Haskell 编写的一个简单的井字游戏程序设置一系列测试,但由于一个奇怪的错误被抛出读取,我无法通过我的第一个测试:

Tests.hs:11:61: error:
    * Couldn't match expected type `Int' with actual type `IO Int'
    * In the third argument of `assertEqual', namely
        `(test_user_value x)'
      In the first argument of `TestCase', namely
        `(assertEqual "for (test_user_value 3)," f (test_user_value x))'
      In the expression:
        TestCase
          (assertEqual "for (test_user_value 3)," f (test_user_value x))
   |
11 | test1 = TestCase (assertEqual "for (test_user_value 3)," f (test_user_value x))
   |                                                             ^^^^^^^^^^^^^^^^^
Failed, one module loaded.

值“x”是一个 int,但 Haskell 将其读取为“IO Int”,这是错误的,因为我指定了“x :: Int”。正在测试的函数已被指定为“test_user_value :: Int -> IO Int”,所以我不确定它为什么错误地解释了变量。任何建议,将不胜感激。

4

1 回答 1

3

它实际上不是在抱怨x,而是在抱怨表达式test_user_value x- 请注意,错误消息中带有下划线的是这个表达式。

因为,正如你所指出的,test_user_value :: Int -> IO Intand x :: Int,它遵循test_user_value x :: IO Int- 这正是编译器告诉你不应该在那里的。它期待一个Int,但你给了它IO Int

你可以摆脱Int它。为此,我认为do符号将是最清晰的:

test1 = TestCase $ do
    v <- test_user_value x
    assertEqual "for (test_user_value 3)," f v

或者您可以使用运算符将​​其写得更短一些=<<

test1 = TestCase (assertEqual "for (test_user_value 3)," f =<< test_user_value x)
于 2020-05-12T20:52:08.320 回答