content: {-# LANGUAGE ExistentialQuantification, DeriveDataTypeable #-}
  
  -- The second version (count2) took ages with GHC 6.12
  -- because the typeOf function was not properly memoised
  
  import Data.Typeable
  import System.CPUTime
  
  size :: Int
  size = 40000	-- This was big enough to take 5 seconds in 
         		-- the bad case on my machine.
  
  data Any = forall a. (Typeable a) => Any a
  
  int_type, int_list_type :: TypeRep
  int_type = typeOf (undefined :: Int)
  int_list_type = typeOf (undefined :: [Int])
  
  count1 :: [Any] -> Int
  count1 [] = 0
  count1 (Any x:xs) = count1 xs + (if typeOf x == int_type then 1 else 0)
  
  doTime x = do
    start <- getCPUTime
    putStr "Result: "
    print x
    stop <- getCPUTime
    putStr "Time(sec): "
    print (round $ fromIntegral (stop - start) / 1e12)
      -- The 'round' rounds to an integral number of seconds
      -- Should be zero if things are working right!
  
  main = do
    let list = [MkT | i <- [1..size  :: Int]]
    putStrLn "count1"
    let x = map Any list
    doTime $ count1 x
    doTime $ count1 x
    doTime $ count1 x
    putStrLn ""
    putStrLn "count2"
    let x = map (Any . (:[])) list
    doTime $ count1 x
    doTime $ count1 x
    doTime $ count1 x
  
  data T = MkT deriving Typeable
  