[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?
Paul.
More information about the Haskell-Cafe
mailing list