Monoid: Category == with {
print: % -> ();
times: (%, %) -> %;
one: () -> %;
equal?: (%, %) -> Boolean;
}
MonoidOfZ: Category == Monoid with {
convert: Integer -> %;
}
OddNumbers: MonoidOfZ == add {
attrib(n: Integer);
convert(x: Integer): % ==
if (x rem 2 = 1) then attrib(x) else error;
print(x: %): () == print (x.n);
times(x: %, y: %): % == attrib((x.n) * (y.n));
one(): % == convert(1);
equal?(x: %, y: %): Boolean == (x.n) = (y.n);
}
WordMonoid: Category == Monoid with {
word: String -> %;
}
Word: WordMonoid == add {
attrib(st: String, le: Integer);
word(x: String): % == attrib(x, length(x));
print(x: %): () == print (x.st);
times(x: %, y: %): % == {
z: String := concat(x.st,y.st);
l: Integer := x.le + y.le;
attrib(z,l);
}
one(): % == word(empty(),0);
equal?(x: %, y: %): Boolean == {
if (x.le ~= y.le) then return false;
equal?(x.st,y.st);
}
}
main(): () == {
x: Word := word("Hello ");
y: Word := word("Mars.");
xy: Word := times(x,y);
print(xy);
}
main();
Up to the magic function attrib, the program
above could be a fragment of an ALDOR program.
It declares three categories (or interfaces)
and two domains (or classes).
If you are an ALDOR user, you could be surprised
by this attrib function: the goal here is to keep
the grammar, the type checking and the translation simple!
Observe also that the above program relies on three built-in domains, namely Boolean, String and Integer.