[Haskell-cafe] Inferred type is not general enough

Stefan Holdermans sholderm at students.cs.uu.nl
Thu Jul 8 03:30:31 EDT 2004


Ivan,

It's the type of source and destination that is playing you parts. Let's
write them explicitly quantified,

  source      :: forall a b . (Packet a, Location b) => a -> b
  destination :: forall a b . (Packet a, Location b) => a -> b

and reflect on this for a while. This basicly says that whenever I have a
value of a type a that is known to be an instance of Packet, then for each
type b that is known to be an instance of Location, source will give me an
instance of that type b. (The same holds for destination, of course.)

So now, I can define a new data type

  data Foo = Foo ,

declare it an instance of Location

  instance Location Foo where
    point foo = "foo" ,

and write the following function, knowing that TestPacket is an instance of
Packet,

  getFoo        :: Packet -> Foo
  getFoo packet =  source packet .

But, clearly, your implementation of source for TestPacket is not prepared
to produce a value of Foo. Instead, it always produce a value of
TestLocation. To be well-typed, however, it shoud be capable of producing a
value of any type that is declared an instance of Location.

A possible solution would be to fix the type of the returned location for
each instance of Packet,

  class (Location b) => Packet a b where
    source, destination :: a -> b

but this requires multi-parameter type classes, which are not part of
Haskell 98. Another approach would be to enrich the interface of the
Location class, so that it provides support for the construction of
locations.

HTH,

Stefan




More information about the Haskell-Cafe mailing list