haskellhunit

How to test my own data Types using HUnit in Haskell?


Part of Queue.hs:

module Queue ( Queue, emptyQueue, isEmptyQueue, enQueue, deQueue ) where

data Queue a = EmptyQueue | Single a | Q a ( Queue a ) a deriving (Show, Eq)

emptyQueue :: Queue a
emptyQueue = EmptyQueue

enQueue :: a -> Queue a -> Queue a
enQueue x EmptyQueue = Single x
enQueue x (Single q) = Q q (EmptyQueue) x
enQueue x (Q qf q qb) = Q qf (enQueue qb q) x

I was using print, see if them correct one by one. Now I want to test them using HUint.

Main.hs:

module Main where
import Queue 
import Test.HUnit

test1 = TestCase $ assertEqual "" (Single 'a'::Queue Char) $ enQueue 'a' emptyQueue
tests = TestList [TestLabel "test1" test1]

main = do runTestTT tests

Here's what I got:

*Queue> :r
[2 of 2] Compiling Main             ( Main.hs, interpreted )

Main.hs:5:36: Not in scope: data constructor ‘Single’
Failed, modules loaded: Queue.

So how can I fix it?


Solution

  • Seems the Queue datatype should be abstract and opaque, so exposing all constructors is not a good idea. However, you can split your implementation into two submodules:

    module Queue.Internal where --expose all internal stuff
    
    data Queue = <...>
    
    
    module Queue (Queue, emptyQueue, <...>) where --expose user API only
    
    import Queue.Internal
    
    
    module Queue.Tests where
    
    import Queue.Internal --to get access to „guts“
    
    test = <...>
    
    
    module Main where
    
    import Queue --to just use the type
    

    Some library types (like ByteStrings) are made this way.