[MLton] Structures inside a function?

Wesley W. Terpstra terpstra@gkec.tu-darmstadt.de
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_ =
  sig
    include INTEGRAL_DOMAIN_
    val QUO: (t * t) -> (t * t)
  end
signature EUCLIDEAN_DOMAIN =
  sig
    include EUCLIDEAN_DOMAIN_
    structure Addition : ABELIAN_GROUP where type t = t
    structure Multiplication : ABELIAN_MONOID where type t = t
  end

(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) =
  struct
    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
  end

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