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\"")))