# [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.