Inhomogeneous lists are one example given for a new ghc 7.6 dependent object type:
data HList :: [*] -> * where HNil :: HList '[] HCons:: a -> HList t -> HList (a ': t)
The list of li examples compiles fine:
li = HCons "Int: " (HCons 234 (HCons "Integer: " (HCons 129877645 HNil)))
Obviously, we would like the HList to be in the Show class, but I can only create an instance of the working class that uses mutually recursive constraints (superclasses):
instance Show (HList '[]) where show HNil = "[]" instance (Show a, Show' (HList t)) => Show (HList (a ': t)) where show l = "[" ++ show' l ++ "]" class Show' a where show' :: a -> String instance Show' (HList '[]) where show' HNil = "" instance (Show a, Show' (HList t)) => Show' (HList (a ': t)) where show' (HCons hl) = case l of HNil -> show h HCons _ _ -> show h ++ ", " ++ (show' l)
The code compiles fine, and li displays correctly. The necessary compilation flags are:
{-
I tried many variations of the following much more direct definition, but it does not compile if I cannot understand the ghc error messages:
instance Show (HList '[]) where show HNil = "[]" instance (Show a, Show (HList t)) => Show (HList (a ': t)) where show l = "[" ++ (show' l) ++ "]" where show' (HCons hs) = case s of HNil -> show h HCons _ _ -> show h ++ ", " ++ (show' s)
Some Haskell / ghc experts may understand why this may not work, and I would be happy to hear the reason.
thanks
Hans Peter
Thank you, Hammar, for your two nice working examples, having improved in my first example.
But I still do not understand why my second example does not work. You say that "... show" knows how to show the current item type, not the rest. "But will this comment not be applied in the following (working) code:
instance Show (HList '[]) where show HNil = "" instance (Show a, Show (HList t)) => Show (HList (a ': t)) where show (HCons ht) = case t of HNil -> show h HCons _ _ -> show h ++ ", " ++ (show t)