<HTML><FONT FACE=arial,helvetica><FONT  SIZE=4 FAMILY="SERIF" FACE="Times New Roman" LANG="0">First, a disclaimer.  I've been toying around with polymorphism as understood 
<BR>in an OOP sense in a number of different languages.  I realize that Mercury 
<BR>isn't geared towards such things, but I use it as a method to learn about 
<BR>various programming languages.  Mercury is definitely unique in what it tries 
<BR>to do, so I've been trying off and on to learn what I can about the language.
<BR>
<BR>I've been playing around with Mercury for a while, and just haven't quite got 
<BR>a handle on the syntax of typeclasses (not to mention some of the major 
<BR>concepts of the language).  I don't really know enuf about the language to 
<BR>frame my questions in a coherent manner, but I figure the only way to learn 
<BR>is to ask dumb questions.  I apologize for not making the questions a bit 
<BR>more straightforward but hopefully the code is fairly easy to understand (at 
<BR>least that was the intention).  :-)
<BR>
<BR>The code I'm trying to construct is the toy example of shape inheritance 
<BR>(circle extends shape, etc...).  I include what little I've been able to 
<BR>accomplish at the end of this message (sorry for the long post).  A couple of 
<BR>issues that I've had at this point are:
<BR>
<BR>
<BR>1).  For some reason, MMC complains about not being able to find shape.int3.  
<BR>I am trying to play with a sort of limited inheritance in this situation 
<BR>where the circleClass inherits the method signatures of the shapeClass.  If I 
<BR>manually copy the file shape.int2 into the requested file shape.int3, 
<BR>everything seems to work fine.  I don't know enuf about the compiler but a 
<BR>wild guess would be that each level of inheritance that is split across 
<BR>modules is adding one to the index of the module file.  Of course that's a 
<BR>WAG.  Anyhow, is there a reason why MMC exhibits this behavior?
<BR>
<BR>      Here's the calls to MMC for the interface generate:
<BR>
<BR>            mmc --make-int shape.m
<BR>            mmc --make-int circle.m
<BR>
<BR>      Here's the error message I get when it tries to create the interface 
<BR>for circle.m:
<BR>
<BR>            --: not found
<BR>            mercury_compile: can't open file `shape.int3'.
<BR>            Error reading short interface files.
<BR>            `circle.int' and `circle.int2' not written.
<BR>
<BR>      If I change the calls to the following, I get no complaints:
<BR>
<BR>            mmc --make-int shape.m
<BR>            cp shape.int2 shape.int3
<BR>            mmc --make-int circle.m
<BR>
<BR>
<BR>2).  I'm not sure how to get the methods for the typeclass to be used.  What 
<BR>I wanted is to just expose the record and the typeclass definitions in the 
<BR>interface and then map the specific function to the typeclass within the 
<BR>implementation section of the module.  This would mean that the interface 
<BR>might expose a method called 'getRadius' while the local method can be 
<BR>implemented locally as 'getRadius_Circle'.  If I try to access the method by 
<BR>the name of the typeclass method, I get an error message about an unsatisfied 
<BR>constraint.
<BR>
<BR>      Here's the call in the main routine that causes the problem:
<BR>
<BR>            draw_Circle(setRadius(ACircle, 30))
<BR>
<BR>      Here's the error message:
<BR>
<BR>            In clause for predicate `polymorph:main/2':
<BR>              unsatisfiable typeclass constraint(s):
<BR>              `circle:circleClass((circle:circleRecord))'.
<BR>
<BR>      However, if I don't use the typeclass and directly go to the defined 
<BR>function, it works:
<BR>
<BR>            draw_Circle(setRadius_Circle(ACircle, 30))
<BR>
<BR>
<BR>I think I'm missing something obvious about the way that typeclasses work, 
<BR>but I thought the purpose was to map method names from local implementation 
<BR>names into a globally recognized method name.  The mapping of the class 
<BR>method names into the implementation names is taken care of by the instance 
<BR>declarations.  Just wondering what I am missing here?
<BR>
<BR>Along these lines, I really didn't want to put the local implementation mode 
<BR>into the interface section.  If I could get the method names to map off of 
<BR>the class, I'd probably be able to push the local names into the 
<BR>implementation section.
<BR>
<BR>
<BR>3).  Also along similar lines, I was having difficulty getting the compiler 
<BR>to accept pred(draw/3) in the instance declaration.  The pred() compiles fine 
<BR>in the typeclass statement but it complains if I try to map it within the 
<BR>instance.  I see in the documentation that it is allowed to mix predicates 
<BR>and functions within the instance declarations.  The only proviso that I see 
<BR>is that all the example predicates take a single constraint.  In this case, 
<BR>the pred is doing some simple io so it requires the single argument as well 
<BR>as the two tag along arguments for input/output.  In the code that compiles 
<BR>and runs, I just commented out the line in the instance declaration:
<BR>
<BR>      Here's the line of code that causes the problem:
<BR>
<BR>            :- instance shapeClass(circleRecord) where [
<BR>               pred(draw/3) is draw_Circle,
<BR>
<BR>      Here's the error message that I get:
<BR>
<BR>            In instance declaration for `shape:shapeClass/1': incorrect
<BR>              method name(s): predicate `shape:draw/3' .
<BR>
<BR>Anyhow, what exactly am I doing wrong here?
<BR>
<BR>
<BR>Thanks in advance for any help.
<BR>
<BR>Here's the code as it currently runs.
<BR>
<BR>%%%%%%%%%%%%%%%%%%%%%%%%%%%%% polymorph.m %%%%%%%%%%%%%%%%%%%%%%%%%%%
<BR>:- module polymorph.
<BR>
<BR>:- interface.
<BR>:- import_module io, int, list, shape, circle.
<BR>:- pred main(io__state, io__state).
<BR>:- mode main(di, uo) is det.
<BR>
<BR>:- implementation.
<BR>
<BR>main -->
<BR>   { Scribble = [circleRecord(10, 20, 5), circleRecord(15, 25, 8)] },
<BR>   { ACircle = circleRecord(0, 0, 15) },
<BR>   drawLoop(Scribble),
<BR>   draw_Circle(setRadius_Circle(ACircle, 30)).
<BR>
<BR>:- pred drawLoop(list(circleRecord), io__state, io__state).
<BR>:- mode drawLoop(in, di, uo) is det.
<BR>drawLoop([]) --> [].
<BR>drawLoop([Hd | Tl]) -->
<BR>   draw_Circle(Hd),
<BR>   draw_Circle(rMoveTo_Circle(Hd, 100, 100)),
<BR>   drawLoop(Tl).
<BR>
<BR>%%%%%%%%%%%%%%%%%%%%%%%%%%%%% shape.m %%%%%%%%%%%%%%%%%%%%%%%%%%%
<BR>:- module shape.
<BR>
<BR>:- interface.
<BR>:- import_module io, int.
<BR>
<BR>% declare method interfaces for the shape superclass
<BR>:- typeclass shapeClass(This) where [
<BR>   pred draw(This, io__state, io__state),
<BR>   func getX(This) = int,
<BR>   func getY(This) = int,
<BR>   func setX(This, int) = This,
<BR>   func setY(This, int) = This,
<BR>   func moveTo(This, int, int) = This,
<BR>   func rMoveTo(This, int, int) = This
<BR>].
<BR>
<BR>:- implementation.
<BR>
<BR>
<BR>%%%%%%%%%%%%%%%%%%%%%%%%%%%%% circle.m %%%%%%%%%%%%%%%%%%%%%%%%%%%
<BR>:- module circle.
<BR>
<BR>:- interface.
<BR>:- import_module io, int, shape.
<BR>
<BR>% declare the constructor for circle class
<BR>:- type circleRecord
<BR>   ---> circleRecord(
<BR>      x :: int,
<BR>      y :: int,
<BR>      radius :: int
<BR>   ).
<BR>
<BR>% declare method interfaces for circle subclass
<BR>:- typeclass circleClass(This) <= shapeClass(This) where [
<BR>   func getRadius(This) = int,
<BR>   func setRadius(This, int) = circleRecord
<BR>].
<BR>
<BR>
<BR>:- pred draw_Circle(circleRecord, io__state, io__state).
<BR>:- mode draw_Circle(in, di, uo) is det.
<BR>
<BR>:- func getX_Circle(circleRecord) = int.
<BR>:- mode getX_Circle(in) = out is det.
<BR>
<BR>:- func getY_Circle(circleRecord) = int.
<BR>:- mode getY_Circle(in) = out is det.
<BR>
<BR>:- func getRadius_Circle(circleRecord) = int.
<BR>:- mode getRadius_Circle(in) = out is det.
<BR>
<BR>:- func setX_Circle(circleRecord, int) = circleRecord.
<BR>:- mode setX_Circle(in, in) = out is det.
<BR>
<BR>:- func setY_Circle(circleRecord, int) = circleRecord.
<BR>:- mode setY_Circle(in, in) = out is det.
<BR>
<BR>:- func setRadius_Circle(circleRecord, int) = circleRecord.
<BR>:- mode setRadius_Circle(in, in) = out is det.
<BR>
<BR>:- func moveTo_Circle(circleRecord, int, int) = circleRecord.
<BR>:- mode moveTo_Circle(in, in, in) = out is det.
<BR>
<BR>:- func rMoveTo_Circle(circleRecord, int, int) = circleRecord.
<BR>:- mode rMoveTo_Circle(in, in, in) = out is det.
<BR>
<BR>:- implementation.
<BR>
<BR>% map the circle methods for shape superclass
<BR>:- instance shapeClass(circleRecord) where [
<BR>   %  pred(draw/3) is draw_Circle,
<BR>   func(getX/1) is getX_Circle,
<BR>   func(getY/1) is getY_Circle,
<BR>   func(setX/2) is setX_Circle,
<BR>   func(setY/2) is setY_Circle,
<BR>   func(moveTo/3) is moveTo_Circle,
<BR>   func(rMoveTo/3) is rMoveTo_Circle
<BR>].
<BR>
<BR>% map the methods for circle subclass
<BR>:- instance circleClass(circleRecord) where [
<BR>   func(getRadius/1) is getRadius_Circle,
<BR>   func(setRadius/2) is setRadius_Circle
<BR>].
<BR>
<BR>% method definitions for the circle class follow
<BR>getX_Circle(This) = This^x.
<BR>getY_Circle(This) = This^y.
<BR>getRadius_Circle(This) = This^radius.
<BR>setX_Circle(circleRecord(_,Y,Radius), X) = circleRecord(X, Y, Radius).
<BR>setY_Circle(circleRecord(X,_,Radius), Y) = circleRecord(X, Y, Radius).
<BR>setRadius_Circle(circleRecord(X,Y,_), Radius) = circleRecord(X, Y, Radius).
<BR>moveTo_Circle(circleRecord(_,_,Radius), X, Y) = circleRecord(X, Y, Radius).
<BR>rMoveTo_Circle(circleRecord(X,Y,Radius), DX, DY) = circleRecord(X+DX, Y+DY, 
<BR>Radius).
<BR>
<BR>draw_Circle(This) -->
<BR>   io__write_string("Drawing a circle at:("),
<BR>   io__write_int(getX_Circle(This)),
<BR>   io__write_string(","),
<BR>   io__write_int(getY_Circle(This)),
<BR>   io__write_string("), radius "),
<BR>   io__write_int(getRadius_Circle(This)),
<BR>   io__nl.
<BR>
<BR></FONT></HTML>