[Haskell-cafe] Help with complicated type inference

Paul Johnson paul at cogito.org.uk
Sun Apr 27 07:07:58 EDT 2008

I'm trying to write an AMQP framing layer.  AMQP has two very similar 
union types: there is a "variant" that contains a single item, and an 
"array" which consists of a list of elements of the same type.  So I 
thought I could define a "Unit" type container thus:

 > newtype Unit a = Unit {unUnit :: a}

So now I can say:

 > type AmqpVariant = AmqpVariantBase Unit
 > type AmqpArray = AmqpVariantBase []

Then the AmqpVariantBase type looks something like this (except that it 
doesn't work, see below):

 > data forall a . (AmqpWire a, AmqpWire (c a)) =>
 >    AmqpVariantBase c = AmqpVarBin8 (c Bin8)
 >       | AmqpVarInt8 (c Int8)
 >       | AmqpVarUint8 (c Word8)
 >       | AmqpVarChar (c Word8)
 >       | AmqpVarBoolean (c Bool)
 >       | AmqpVarBin16 (c Bin16)
 >       | AmqpVarInt16 (c Int16)
 >       | AmqpVarUint16 (c Word16)
 >       | AmqpVarBin32 (c Bin32)
 >       | AmqpVarInt32 (c Int32)
 >          -- And on for about 20 more types, including compound types.

All AMQP types have to be seralised, so I've defined a class "AmqpWire" 
for serialisation in AMQP format.  All the individual types (Bin8, Int8 
etc) are instances of this class.  I've also defined instances for Unit 
and [] such as:

 > instance (AmqpWire a) => AmqpWire (Unit a) where
 >    amqpPut = amqpPut . unUnit
 >    amqpGet = map Unit amqpGet

The problem is with the type constraint for AmqpVariantBase.  I need to 
say "AmqpWire (c a)" without explicitly listing all the values of "a" 
(i.e. Bin8, Int8, etc) because any time I use AmqpVariantBase I have to 
repeat the same constraint.  How do I do this?


More information about the Haskell-Cafe mailing list