[MLton] Structures inside a function?

Wesley W. Terpstra terpstra@gkec.tu-darmstadt.de
Thu, 20 Jan 2005 11:22:12 +0100


On Wed, Jan 19, 2005 at 08:22:57PM -0500, Matthew Fluet wrote:
> Perhaps you can make ResidueWithoutModulus and MathWithoutModulus functors 
> that parameterize each function requiring the modulus with the explicit 
> modulus argument.
> 
> You can then make Residue and Math essentially special cases of the above, 
> where you have the modulus up front and can simplify the exported 
> functions to not have the modulus argument.
> 
> Then you could write:
> 
> functor Factor(E : EUCLIDEAN_DOMAIN) =
>   struct
>     structure R = ResidueWithoutModulus(struct structure Base = E)
>     structure M = MathWithoutModulus(R)
> 
>     fun factor x =
>       let
> 	open M
>         val f1 = f1 x
>         val f2 = f2 x
>       in
>         (* use various methods defined in Math to factor x *)
>       end
>   end
> 
> where each of the fi functions are from the MathWithoutModulus functor.

The problem is that Math(...) is used on a RING.
A RING includes multiplication, addition, comparison, and some guarantees.
There is nothing to say a RING even _has_ a modulus.

For example: the integers form a ring, as do matrixes, and numbers in a
residue ring (which has a modulus). The methods in Math(...) are built using
only the RING interface. The modulus is something which should not be
visible at the level of the Math(...) functor because then you couldn't use
the other two rings with it.

Any other suggestions?

I suppose I could incorporate some sort of generalized state which has
RING-specific type. For everything else I could use unit, but here include
the modulus.

However, how would I then curry this with the operators?
Right now, for example, a GROUP looks like:

signature GROUP =
  sig
    type t
    (* type s  (* add some sort of magic state? *) *)
    val EQ:  (* s -> *)  (t * t) -> t 
    val MUL: (* s -> *)  (t * t) -> t
    val DIV: (* s -> *)  (t * t) -> t
    val INV: (* s -> *)  t -> t
    val one: (* s -> *)  t
    ...
  end

I then  have a functor called GroupBinding like:

functor GroupMulPercent(G : GROUP) = 
  struct
    val (op *%) = G.MUL
    val (op /%) = G.DIV
    val (op !%) = G.INV
    ...
  end

Right now code that uses a GROUP does something like this:

structure P = PolynomialOverField(Mersenne31)
structure G = P.Multiplication
structure B = GroupMulPercent(G)
open B

Is there a way to put the currying into the binding functor GroupMulPercent?

The list of functions in my example is small, but in the case of rings or
polynomials gets quite large. The binding is designed so you can use many
different groups with multiplication at once. eg: *%, *$, ...

-- 
Wesley W. Terpstra