[MLton] Structures inside a function?
Wesley W. Terpstra
Fri, 21 Jan 2005 21:51:33 +0100
On Fri, Jan 21, 2005 at 08:21:29AM -0800, Stephen Weeks wrote:
> > I suspect that you really want a whole family of functors:
> > functor GroupOps (structure G : GROUP) = ...
> > functor GroupOpsPercent (structure G : GROUP) = ...
> > functor GroupOpsDollar (structure G : GROUP) = ...
> > functor GroupOpsHash (structure G : GROUP) = ...
Yep, that's exactly what I do now.
I don't have GroupOps, however. I agree it might be more convenient, but one
is usually working with at least two things at once in these algorithms.
Also, I find it helps me to identify what is an actual method call when
there's a % on it; these operations are often not constant time.
The unfortunate thing is that I need to have one functor for every %, $, #,
etc and the Group, Ring, etc pairs. This is because the more derived
structures have more operations. I also include exponentiation.
Incidentally, you want GroupAdd*Ops and GroupMul*Ops. These bind a group to
either +, -, ~, =, != or *, /, !, =, !=. This works out well because then
RINGs get operations from the two substructures Addition and Multiplication.
I also (for EuclideanDomains) don't have div or mod...
The problem was that mod% and div% don't seem to parse. ;)
Instead, I used /%, %%, and //%. The implementation of div and mod are
nearly always combined; computing one gets you the other.
signature EUCLIDEAN_DOMAIN_ =
val QUO: (t * t) -> (t * t)
signature EUCLIDEAN_DOMAIN =
structure Addition : ABELIAN_GROUP where type t = t
structure Multiplication : ABELIAN_MONOID where type t = t
(I had to split this signature appart to make 'include' work even though
derived structures change the signature of Addition and Multiplication)
functor EuclideanDomainPercent(E : EUCLIDEAN_DOMAIN) =
local structure S = AbelianMonoidMulPercent(E.Multiplication) in open S end
local structure S = AbelianGroupAddPercent(E.Addition) in open S end
val #% = fn e => E.Multiplication.one ++% e
val (op /%) = #1 o E.QUO
val (op %%) = #2 o E.QUO
val (op //%) = E.QUO
The #% allows one to get handy constants that must exist in any UNITARY_RING.
Eg: val two = #%2 (could be =% 0 say, modulo 2, but it exists). ++% is
exponentiation over the +% operator (**% for multiplication).
Wesley W. Terpstra