content: {-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
  {-# LANGUAGE TypeFamilies #-}
  {-# LANGUAGE FlexibleInstances #-}
  {-# LANGUAGE FlexibleContexts #-}
  {-# LANGUAGE TypeOperators #-}
  
  module T5359b where
  
  -----------------------------------------------------------------------------
  -- Base
  -----------------------------------------------------------------------------
  infixr 5 :+:
  infixr 6 :*:
  
  data U       = U              
  data a :+: b = L a | R b      
  data a :*: b = a :*: b        
  newtype Rec a   = Rec a       
  
  class Representable a where
    type Rep a
    to   :: Rep a -> a
    from :: a -> Rep a
  
  
  data Tree = Leaf | Bin Int Tree Tree
  
  instance Representable Tree where
    type Rep Tree =     U
                        :+: (Rec Int :*: Rec Tree :*: Rec Tree)
  
    from (Bin x l r) = R ((Rec x :*: Rec l :*: Rec r))
    from Leaf        = L (U)
  
    to (R ((Rec x :*: (Rec l) :*: (Rec r)))) = Bin x l r
    to (L (U))                               = Leaf
  
  --------------------------------------------------------------------------------
  -- Generic enum
  --------------------------------------------------------------------------------
  
  class Enum' a where
    enum' :: [a]
  
  instance Enum' U where enum' = undefined
  instance (Enum' a) => Enum' (Rec a) where enum' = undefined
  instance (Enum' f, Enum' g) => Enum' (f :+: g) where enum' = undefined
  instance (Enum' f, Enum' g) => Enum' (f :*: g) where enum' = undefined
  
  
  -- This INLINE pragma is essential for the bug
  {-# INLINE genum #-}
  genum :: (Representable a, Enum' (Rep a)) => [a]
  -- The definition of genum is essential for the bug
  genum = map to enum'
  
  
  instance Enum' Tree where enum' = genum
  instance Enum' Int  where enum' = []
  
  -- This SPECIALISE pragma is essential for the bug
  {-# SPECIALISE genum :: [Tree] #-}
  