Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing a function that takes an empty list

I'm trying to write a unit test for the simple function that takes a list and just returns it,

func :: [a] -> [a]
func x = x

using the test code to test that it works as expected when given an empty list

emptyListTest :: Test
emptyListTest = TestCase $ assertEqual "for (func [])," [] $ func []

main :: IO Counts
main = runTestTT $ TestList [emptyListTest]

However, I get the error

No instance for (Show a0) arising from a use of `assertEqual'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
  instance Show Double -- Defined in `GHC.Float'
  instance Show Float -- Defined in `GHC.Float'
  instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
    -- Defined in `GHC.Real'
  ...plus 28 others
In the expression: assertEqual "for (func [])," []
In the second argument of `($)', namely
  `assertEqual "for (func [])," [] $ func []'
In the expression:
  TestCase $ assertEqual "for (func [])," [] $ func []

Other tests with non-empty lists work fine, and the function works fine when testing manually by calling func [] in ghci.

I've also noticed that if I create a dummy type, and make a list taking elements of that type (if that's the correct way of saying it), then passing that to the test seems to work, and the test passes

data Dummy = Dummy
    deriving(Eq, Show)

emptyList :: [Dummy]
emptyList = []

emptyListTest :: Test
emptyListTest = TestCase $ assertEqual "for (func [])," [] $ func emptyList

Why is this? Is there a way to test functions with an empty list without going down the dummy type route?

like image 322
Michal Charemza Avatar asked Feb 21 '26 18:02

Michal Charemza


2 Answers

Well, the error tells you exactly what is wrong. Read it.

 The type variable `a0' is ambiguous

So, type your variable! GHC can't possibly know what type to use to test unless you do.

emptyListTest = TestCase $ assertEqual "for (func [])," [] $ func ([] :: [Int])

You may have to enable an extension to do it inline.

like image 169
alternative Avatar answered Feb 23 '26 23:02

alternative


You need to provide a type for the empty list - otherwise GHC doesn't know what kind of list you are using.

One possible fix:

.... assertEqual "for (func [])," [] $ func ([] :: [Int])
like image 21
ErikR Avatar answered Feb 24 '26 01:02

ErikR



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!