[mercury-users] Newbie questions about typeclasses
Mark Anthony BROWN
dougl at cs.mu.OZ.AU
Tue Apr 24 16:55:40 AEST 2001
Critterrathman at aol.com writes:
> First, a disclaimer. I've been toying around with polymorphism as understood
> in an OOP sense in a number of different languages. I realize that Mercury
> isn't geared towards such things, but I use it as a method to learn about
> various programming languages. Mercury is definitely unique in what it tries
> to do, so I've been trying off and on to learn what I can about the language.
>
> I've been playing around with Mercury for a while, and just haven't quite got
> a handle on the syntax of typeclasses (not to mention some of the major
> concepts of the language). I don't really know enuf about the language to
> frame my questions in a coherent manner, but I figure the only way to learn
> is to ask dumb questions. I apologize for not making the questions a bit
> more straightforward but hopefully the code is fairly easy to understand (at
> least that was the intention). :-)
>
> The code I'm trying to construct is the toy example of shape inheritance
> (circle extends shape, etc...). I include what little I've been able to
> accomplish at the end of this message (sorry for the long post). A couple of
> issues that I've had at this point are:
>
>
> 1). For some reason, MMC complains about not being able to find shape.int3.
> I am trying to play with a sort of limited inheritance in this situation
> where the circleClass inherits the method signatures of the shapeClass. If I
> manually copy the file shape.int2 into the requested file shape.int3,
> everything seems to work fine. I don't know enuf about the compiler but a
> wild guess would be that each level of inheritance that is split across
> modules is adding one to the index of the module file. Of course that's a
> WAG. Anyhow, is there a reason why MMC exhibits this behavior?
Because mmc has only generated the "interface" files, not the "short
interface" files. When compiling multi-module programs, it can be difficult
to manually figure out which interface files need to be generated, so we
recommend you use mmake to do it automatically. E.g.:
mmake main_module.depend
mmake main_module
This should ensure that mmc generates all the interface files required.
>
> Here's the calls to MMC for the interface generate:
>
> mmc --make-int shape.m
> mmc --make-int circle.m
>
> Here's the error message I get when it tries to create the interface
> for circle.m:
>
> --: not found
> mercury_compile: can't open file `shape.int3'.
> Error reading short interface files.
> `circle.int' and `circle.int2' not written.
>
> If I change the calls to the following, I get no complaints:
>
> mmc --make-int shape.m
> cp shape.int2 shape.int3
> mmc --make-int circle.m
>
That won't work in general. You may need to do 'mmake clean' to remove
any extra files that are lying around (you'll need to do this after the
'mmake main_module.depend' line above, and before the 'mmake main_module'
line).
>
> 2). I'm not sure how to get the methods for the typeclass to be used. What
> I wanted is to just expose the record and the typeclass definitions in the
> interface and then map the specific function to the typeclass within the
> implementation section of the module. This would mean that the interface
> might expose a method called 'getRadius' while the local method can be
> implemented locally as 'getRadius_Circle'. If I try to access the method by
> the name of the typeclass method, I get an error message about an unsatisfied
> constraint.
>
> Here's the call in the main routine that causes the problem:
>
> draw_Circle(setRadius(ACircle, 30))
>
> Here's the error message:
>
> In clause for predicate `polymorph:main/2':
> unsatisfiable typeclass constraint(s):
> `circle:circleClass((circle:circleRecord))'.
>
> However, if I don't use the typeclass and directly go to the defined
> function, it works:
>
> draw_Circle(setRadius_Circle(ACircle, 30))
>
>
> I think I'm missing something obvious about the way that typeclasses work,
> but I thought the purpose was to map method names from local implementation
> names into a globally recognized method name. The mapping of the class
> method names into the implementation names is taken care of by the instance
> declarations. Just wondering what I am missing here?
>
> Along these lines, I really didn't want to put the local implementation mode
> into the interface section. If I could get the method names to map off of
> the class, I'd probably be able to push the local names into the
> implementation section.
It sounds like you want abstract typeclass instances. In the interface
section, mention the type and instance but don't give any definition,
like so:
:- type circleRecord.
:- instance shapeClass(circleRecord).
:- instance circleClass(circleRecord).
Then in the implementation section, give full definitions of the type
and instances.
>
> 3). Also along similar lines, I was having difficulty getting the compiler
> to accept pred(draw/3) in the instance declaration. The pred() compiles fine
> in the typeclass statement but it complains if I try to map it within the
> instance. I see in the documentation that it is allowed to mix predicates
> and functions within the instance declarations. The only proviso that I see
> is that all the example predicates take a single constraint. In this case,
> the pred is doing some simple io so it requires the single argument as well
> as the two tag along arguments for input/output. In the code that compiles
> and runs, I just commented out the line in the instance declaration:
>
> Here's the line of code that causes the problem:
>
> :- instance shapeClass(circleRecord) where [
> pred(draw/3) is draw_Circle,
>
> Here's the error message that I get:
>
> In instance declaration for `shape:shapeClass/1': incorrect
> method name(s): predicate `shape:draw/3' .
>
> Anyhow, what exactly am I doing wrong here?
I think it is because you have not given a mode for method draw/3 in the
typeclass declaration in shape.m. You should try adding the line
mode draw(in, di, uo) is det,
to the declaration.
Hope this helps,
Mark.
--------------------------------------------------------------------------
mercury-users mailing list
post: mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the users
mailing list