|
Boost : |
From: Brian McNamara (lorgon_at_[hidden])
Date: 2003-11-16 00:46:45
On Sat, Nov 15, 2003 at 08:54:50PM -0800, Mat Marcus wrote:
> --On Saturday, November 15, 2003 9:55 PM -0500 Brian McNamara
> >No, this is a good example. I have seen it cited before but I had
> >forgotten about it.
>
> Interesting. I thought that I had just contrived it. I'd like to read
> more about this sort of thing if you have additional references.
I seem to recall a discussion on comp.lang.functional which involved the
same "monoid" example (and got me thinking some about "roles"). I can't
find the message I'm thinking of now, but a quick search yields results
like
which at least raise the same issue. The threads may provide some ideas
for the curious, but I don't think they say anything profound or provide
any particularly clever solutions.
> > -- Switching back to Haskell because I need multi-sorted stuff
> > class Nameable thingBeingNamed whosAsking where
> > name :: thingBeingNamed -> string
>
> Just for fun here's a version in the syntax of the papers:
>
> template <class Thing, class Who>
> concept Nameable {
> constraints(Thing thing, Who who){
> string s = name(thing, who);
> }
> };
>
> Alternatively:
>
> template <class Thing, class Who>
> concept Nameable {
> name(Thing, Who)->string;
> };
Actually, my example doesn't take a "who" argument to the function. I
was imagining it being analogous to
template <class Who, class NameableThing>
string name( NameableThing n );
which would have to be invoked as
name<ThePersonWhoIsAsking>( thing );
But whatever; just an example to get the discussion going. :)
> > data RussellShackelford = ...
> > data GrandmaOfRuss = ...
> >
> > instance Nameable RussellShackelford GrandmaOfRuss where
> > name RussellShackelford = "Russell"
> >
> > instance Nameable RussellShackelford a where
> > name RussellShackelford = "Russ"
>
> Presumably a is some sort of predefined placeholder for a universal
> type?
Yes. In a Haskell type, any time "type variables" (names beginning
with lowercase letters) appear, they are implicitly universally
quantified.
> > class Monoid t how where
> > identity_element :: t
> > multiply :: t -> t -> t
>
> Ok, just to make sure that I understand what this means I'll try to
> rewrite this using pseudo-signature syntax as:
> template <class T, class Tag>
> concept Monoid {
> identity_element()->T;
> multiply(T,T)->T;
> };
Yup.
> Sorry, I am not familiar with "Num" -- unless you mean Integer?
My bad, I am assuming too much.
In Haskell, the "Num" type class has operators like + and - and *, it
looks something like
class Num a where
(+) :: a -> a -> a
(-) :: a -> a -> a
(*) :: a -> a -> a
{- etc. -}
Then Integer and Float and Rational and such are all instances of the
Num type class.
> In summary, at this point I see named conformance as possibly
> advantageous, especially as it gives us a place to hang needed
> remapping functionality. I don't think that instance declarations are
> the right place for implementation code to live.
Again, I want to point out that "remapping" is effectively just a
special case of "implementation code". A mapping is just a degenerate
case, where the implementation is merely a forwarding function. (In
some sense, instance declarations are the _only_ place implementation
code can live.)
I'll be keeping an eye out for the post-Kona papers.
-- -Brian McNamara (lorgon_at_[hidden])
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk