{-# 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] #-}