Writing Read instances for HList
This is indeed interesting challenge!

-- Read after H[
class ReadHList (a :: [*]) where
  readHList :: ReadPrec (HList a)

-- Read after element:
-- ] for nil
-- , readHList for cons 
class ReadHListAfter (a :: [*]) where
  readHListAfter :: ReadPrec (HList a)

instance ReadHList '[] where
  readHList = expectP (L.Punc "]") &gt;&gt; return HNil

instance ReadHListAfter '[] where
  readHListAfter = readHList

instance (Read a, ReadHListAfter l) =&gt; ReadHList (a ': l) where
  readHList = ...

-- We could use ReadHList (a ': l) as additional constraint,
-- But then we need UndecidableInstances extension
instance (Read a, ReadHListAfter l) =&gt; ReadHListAfter (a ': l) where
  readHListAfter = ...

-- Parsing HList is trivial as composing functions!
instance ReadHList a =&gt; Read (HList a) where
  readPrec = parens $ do
    expectP (L.Ident "H")
    expectP (L.Punc "[")
    readHList


This way it's a bit more elegant. IMHO.

Compare it to pseudo-codish parsing of lists of known length (aka vectors):

list :: Int -&gt; Parser a -&gt; Parser [a]
list n p =
  token '['
  list' n p

list' :: Int -&gt; Parser a -&gt; Parser [a]
list' 0 _ = token ']' &gt;&gt; return []
list' n p = do
  h &lt;- p
  t &lt;- listTail (n - 1) p
  return (h : t)

listTail :: Int -&gt; Parser a -&gt; Parser [a]
listTail 0 _ = token ']' &gt;&gt; return []
listTail n = do
  h &lt;- p
  token ','
  t &lt;- listTail (n - 1) p
  return (h : t)