[Haskell-cafe] Inferred type is not general enough

Ben Lippmeier Ben.Lippmeier at anu.edu.au
Thu Jul 8 04:38:41 EDT 2004


Ivan..

Uh.. by 'works' I meant 'compiles' :)

Here is a fixed version..

As I understand it, the 2 parameter class (Location loc => Packet p loc) 
means
  "loc is a Location, and types p and loc are related by class Packet"

with just that information, if you try (as you did) something like

$ source TestPacket

Then you've given the compiler the type for 'p' (TestPacket), but it 
won't go the distance and decide that type for 'loc' is TestLocation.. 
even though that's the only instance you've given it.

You can tell the compiler that "The type of 'p' sets the type of 'loc'" 
with a "functional dependency".. which is the "| p -> loc" annotation at 
the end of the class definition in the new version below.


There is a paper which covers exactly this problem, in detail. I suggest 
you read it (I did).

"Type classes with functional dependencies", Mark P. Jones, 2000
You can get it from his homepage at, http://www.cse.ogi.edu/~mpj/

Ben.



Ivan Tihonov wrote:

> It compiles well, but doesn't work for me :(
>

BTW: (email answers are not always real-time :) )

new version:
--------------------------------------
class Location a where
        point        :: a -> String

class Location loc => Packet p loc | p -> loc where
        source       :: p -> loc
        destination  :: p -> loc
        size         :: Num b => p -> b

------------------------------------------------------
data TestLocation
    = TestSource
    | TestDestination
    deriving (Show)

data TestPacket = TestPacket

------------------------------------------------------
instance Location TestLocation where
        point a        = "location"

instance Packet TestPacket TestLocation
 where
        source p       = TestSource
        destination p  = TestDestination
        size p         = 99





More information about the Haskell-Cafe mailing list