haskellvisual-studio-codehunit

Haskell HUnit Function Testing


I'm trying to set up a series of tests for a simple tic tac toe program I've written in Haskell and I'm unable to get past my first test due to a strange error being thrown reading:

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.

The value 'x' is an int but Haskell is reading it as 'IO Int' which is wrong, as I've specified "x :: Int". The function being tested has already been specified as "test_user_value :: Int -> IO Int" so I'm unsure why it is interpreting the variable incorrectly. Any suggestions would be appreciated.


Solution

  • It's not actually complaining about x, it's complaining about the expression test_user_value x - note that it is this expression that is underlined in the error message.

    Since, as you have indicated, test_user_value :: Int -> IO Int and x :: Int, it follows that test_user_value x :: IO Int - and that's exactly what the compiler tells you shouldn't be there. It's expecting an Int, but you gave it IO Int.

    You can get an Int out of it though. To do that, I think the do notation would be the clearest:

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

    Or you could write it a bit shorter using the =<< operator:

    test1 = TestCase (assertEqual "for (test_user_value 3)," f =<< test_user_value x)