1{-# OPTIONS -fglasgow-exts #-} 2 3module HList (tests) where 4 5{- 6 7This module illustrates heterogeneously typed lists. 8 9-} 10 11import Test.HUnit 12 13import Data.Typeable 14 15 16-- Heterogeneously typed lists 17type HList = [DontKnow] 18 19data DontKnow = forall a. Typeable a => DontKnow a 20 21-- The empty list 22initHList :: HList 23initHList = [] 24 25-- Add an entry 26addHList :: Typeable a => a -> HList -> HList 27addHList a l = (DontKnow a:l) 28 29-- Test for an empty list 30nullHList :: HList -> Bool 31nullHList = null 32 33-- Retrieve head by type case 34headHList :: Typeable a => HList -> Maybe a 35headHList [] = Nothing 36headHList (DontKnow a:_) = cast a 37 38-- Retrieve tail by type case 39tailHList :: HList -> HList 40tailHList = tail 41 42-- Access per index; starts at 1 43nth1HList :: Typeable a => Int -> HList -> Maybe a 44nth1HList i l = case (l !! (i-1)) of (DontKnow a) -> cast a 45 46 47---------------------------------------------------------------------------- 48 49-- A demo list 50mylist = addHList (1::Int) $ 51 addHList (True::Bool) $ 52 addHList ("42"::String) $ 53 initHList 54 55-- Main function for testing 56tests = ( show (nth1HList 1 mylist :: Maybe Int) -- shows Just 1 57 , ( show (nth1HList 1 mylist :: Maybe Bool) -- shows Nothing 58 , ( show (nth1HList 2 mylist :: Maybe Bool) -- shows Just True 59 , ( show (nth1HList 3 mylist :: Maybe String) -- shows Just "42" 60 )))) ~=? output 61 62output = ("Just 1",("Nothing",("Just True","Just \"42\"")))