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



_______________________________________________
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to