[MLton] withtype in signature?

Stephen Weeks MLton@mlton.org
Tue, 6 Sep 2005 10:30:57 -0700


> I want to have something like
>      datatype test = A of foo * baz | B
>      withtype foo = string * test
>      and baz = int
> in a signature, but I see that it is explicitly forbidden by ml.grm.
...
> How do I achieve the same effect? (a public recursive datatype)

The way I typically work around the absence of withtype in signatures
is to make all the withtypes be datatypes.  That is,

  datatype test = A of foo * baz | B
  and foo = Foo of string * test
  and baz = Baz of int

This has the additional benefit that sharing is allowed on the
signature (it normally would not be because of the nontrivial
definition of foo).

If you insist on having nontrivial type definitions in signatures, you
could also use type constructors that abstract over the recursive
type.

  type 'a foo' = string * 'a
  type 'a baz' = int
  datatype test = A of test foo' * test baz' | B
  type foo = test foo'
  type baz = test baz'

Another approach is to use use type sharing to tie the knot after the
fact.

  type test'
  type foo = string * test'
  type baz = int
  datatype test = A of foo * baz | B
  sharing type test = test'

Beware that this approach often tickles an SML/NJ type checker bug, as
it does in this case, and so isn't all that practical (if you use
SML/NJ).


In any case, I strongly recommend the datatype approach, as it is
concise, plays well with other aspects of the language, and works in
all compilers.