[MLton] Structures inside a function?

Stephen Weeks MLton@mlton.org
Fri, 21 Jan 2005 13:43:49 -0800


> The only issue I see with it is that several things depend on the value of
> the modulus. For example, the order of the resulting ring (number of
> elements) is calculated from it. Furthermore, functors like
> 	functor DiscreteLogarithm(G : CYCLIC_GROUP) = ..
> need to factor (in the integer sense) the order of groups.
> 
> This calculation right now is performed at structure instantiation.
> Then the logarithm method re-uses the factorization in its computations.

It should be easy enough to ensure that the factorization is only
computed once by using laziness/memoization.

You could also make things cleaner by hiding the ref cell and
providing a single function that handles instantiation of the dynamic
part of the structure.  In your original example, this would look like

----------------------------------------------------------------------
signature RESIDUE_PARAM =
   sig
      structure Base: EUCLIDEAN_DOMAIN
   end

functor Residue (P: RESIDUE_PARAM):
   sig
      include RESIDUE_PARAM
      structure R: RING
      val instantiate: {modulus: Base.t} -> unit
   end = ...
functor Math (R: RING) = ...

functor Factor (E : EUCLIDEAN_DOMAIN) =
   struct
      local
	 structure Base = E
	 structure Residue = Residue (structure Base = Base)
	 structure R = Residue.R
	 structure M = Math (R)
      in
	 fun factor x =
	    let
	       val () = Residue.instantiate {modulus = x}
	       open M
	    in
	       (* use various methods defined in Math to factor x *)
	    end
      end
   end
----------------------------------------------------------------------

Residue.instantiate can do all of the computations that Residue used
to do at structure instantiation, and at the time when you want it,
when factor is called.