diff: typeclass user documentation
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu Jan 22 18:17:22 AEDT 1998
On 22-Jan-1998, David Glen JEFFERY <dgj at cs.mu.OZ.AU> wrote:
> * Higher-order:: Mercury supports higher-order predicates and functions,
> with closures, lambda expressions, and currying
> +* Typeclasses:: Mercury supports typeclasses
> * Modules:: Modules allow you to divide a program into smaller parts
Hmm, shouldn't it be "type classes", not "typeclasses"?
Also "Mercury supports type classes" won't help someone who
doesn't already know what they are.
I suggest
* Type classes:: Constrained genericity
or
* Type classes:: Constrained polymorphism
or
* Type classes:: Multiple implementations of a single interface
Perhaps the "Type classes" section should go after the "Modules" section?
> -The type system is based on polymorphic many-sorted logic.
> +The type system is based on many-sorted logic, with polymorphism and
> +typeclasses (@pxref{Typeclasses}).
s/typeclasses/type classes/
s/Typeclasses/Type classes/
> + at node Typeclasses
> + at chapter Typeclasses
ditto
> +Mercury supports constrained polymorphism in the form of typeclasses.
> +Typeclasses allow the programmer to write predicates and functions which
> +operate on variables of any type for which a certain set of operations is
> +defined.
s/type/type (or sequence of types)/
> + at node Typeclass declarations
> + at section Typeclass declarations
> +
> +A @code{typeclass} declaration specifies a set of predicates and/or functions
s/@code/@samp/
(Only here, at the first occurrence. @samp{x} expands to `x'
rather than x).
> +that must be defined on a type for it to be considered to be a member of that
> +typeclass.
s/type/type (or sequence of types)/
s/it/it (them)/
> +The @code{typeclass} declaration gives the name of the typeclass, the
> +names of the type variables which are parameters to the typeclass, and the
> +methods (or operations) which form the interface of the typeclass.
I suggest
s/methods (or operations)/procedures (called "methods")/
or perhaps
s/methods (or operations)/operations (called "methods")/
Perhaps with just `("methods")' rather than `(called "methods")'.
> +For example
> +
> + at example
> +:- typeclass point(T) where [
> + func x_coord(T) = float,
> + mode x_coord(in) = out is det,
> + func y_coord(T) = float,
> + mode y_coord(in) = out is det
> +].
> + at end example
Hmm, the `mode' declarations here are redundant (at least I hope they are! ;-)
since that is the default mode for functions anyway.
It might be better to have both a predicate and a function in the example.
How about using say
:- typeclass point(T) where [
% coords(Point, X, Y):
% X and Y are the cartesian coordinates of Point
pred coords(T, float, float),
mode coords(in, out, out),
% translate(Point, X_Offset, Y_Offset) = NewPoint:
% NewPoint is Point translated X_Offset units in the X direction
% and Y_Offset units in the Y direction
func translate(T, float, float) = T
].
instead?
> +declares the typeclass @code{point}, which refers to points in two dimensional
> +space.
> +
> + at code{pred}, @code{func} and @code{mode} declarations are the only legal
> +declarations inside a @code{typeclass} declaration. The number of parameters to
> +the typeclass (eg. @code{T}) is not limited. Eg. the following is allowed:
s/eg./e.g./
s/Eg./For example,/
> + at example
> +:- typeclass a(T1, T2) where [@dots{}].
> + at end example
> +
> +The only restriction is that the parameters be distinct variables.
> +An @code{instance} declaration gives a type for each parameter of the
> +typeclass. Each of these types must be a simple type, ie. the type must must
> +be a bound type constructor, and if the type is polymorphic the arguments of
> +the type must be distinct type variables.
> eg. @code{int}, @code{list(T)} and
> + at code{map(K,V)} are allowed but @code{T}, @code{list(int)} and @code{map(T,T)}
> +are not.
s/@code/@samp/
s/must be/must either be/
s/ie./i.e./
s/must must/must/
s/bound type constructor/type with no arguments/
s/and if the/or a/
s/eg./e.g.
In other words:
An @samp{instance} declaration gives a type for each parameter of the
typeclass. Each of these types must be either a simple type, ie. a
type with no arguments, or a polymorphic type whose arguments are
all distinct type variables. For example, @code{int}, @code{list(T)} and
@code{map(K,V)} are allowed, but @code{T}, @code{list(int)} and
@code{map(T,T)} are not.
> +There must not be more than one @code{instance} declaration for a particular
> +type (or set of types, in the case of a multi-parameter typeclass).
s/There must not be/A program may not contain/
> +Further instances of the typeclass could be made, eg. a type which represents
> +the point using polar coordinates.
s/eg./e.g./
> + at node Typeclass constraints on predicates and functions
> + at section Typeclass constraints on predicates and functions
> +
> +Mercury allows a typeclass constraint to appear as part of a predicate or
> +functions's type signature. This constrains the values that can be taken
> +by type variables in the signature to belong to particular typeclasses.
> +
> +A typeclass constraint is of the form:
> +
> + at example
> + <= @var{Typeclass}(@var{TypeVariable}, @dots{}), @dots{}
> + at end example
> +
> +where @var{Typeclass} is the name of a typeclass and @var{TypeVariable} is
> +a type variable that appears in the predicate's or function's type signature.
> +
> +For example
> +
> + at example
> +:- pred distance(P1, P2, float) <= point(P1), point(P2).
> +:- pred distance(in, in, out) is det.
> +
> +distance(A, B, Distance) :-
> + XDist = x_coord(A) - x_coord(B),
> + YDist = y_coord(A) - y_coord(B),
> + Distance = sqrt(XDist*XDist + YDist*YDist).
> + at end example
> +
> +In the above example, the @code{distance} predicate is able to calculate the
> +distance between any two points, regardless of their representation, as long
> +as the @code{x_coord} and @code{y_coord} operations have been defined. These
> +constraints are checked statically.
I suggest s/statically/at compile time/
Hmm, I guess if you change the example above, this example looks a bit
worse. You'd have to reword that part.
> + at node Typeclass constraints on typeclass declarations
> + at section Typeclass constraints on typeclass declarations
> +
> +Typeclass constraints may also appear in typeclass declarations, meaning that
> +one typeclass is a ``superclass'' of another.
> +
> +The variables that appear as arguments to the typeclasses in the constraints
> +must also be arguments to the typeclass in question.
> +
> +For example, the following declares the @code{ring} typeclass, which describes
s/@code/@samp/
> +Typeclass constraints on typeclass declarations gives rise to a typeclass
> +relation. This relation must be acyclic.
s/typeclass relation/superclass relation/
I think it would be clearer if you add "That is, it is an error if a
type class is its own (direct or indirect) superclass."
> + at node Typeclass constraints on instance declarations
> + at section Typeclass constraints on instance declarations
> +
> +Typeclass constraints may also be placed upon instance declarations. The
> +variables that appear as arguments to the typeclasses in the constraints must
> +all be type variables that appear in the types in the instance declarations.
> +
> +For example, consider the following declaration of a typeclass of types that
> +may be printed:
> +
> + at example
> +:- typeclass printable(T) where [
> + pred print(T::in, io__state::di, io__state::uo) is det
> +].
> + at end example
This is not a good example, because `io__print' in the standard library
is different to that.
I suggest you use different names, e.g. `portrayable' and `portray'.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list