[MLton] sequenceNonUnit
Matthew Fluet
fluet@cs.cornell.edu
Fri, 5 Aug 2005 21:13:48 -0400 (EDT)
> > Thinking about it briefly, I came up with the following
> > implementation scheme. During the recursive type inference step, the
> > inferred type (which may be a variable) of the "ignored expression"
> > is saved to a list (along with the necessary info to give proper
> > diagnostics). After type inference, a diagnostic would be given for
> > each non-unit type in the list. This way the diagnostic given for
> > the latentError example above, and other similar cases, would
> > (properly) point to the "ignored expression".
> >
> > Would this work and capture the intention of sequenceNonUnit?
>
> Yes. It looks good.
I did a simple implementation of this, and I think it works fairly well.
However, it does print an error/warning for sequence expressions with
non-unit types that are later constrained by a signature to be unit. For
example, from the Basis Library implementation:
Warning: <basis>/misc/dynamic-wind.sml 16.25.
Sequence expression not of type unit.
type: ['a]
in: cleanup ()
Warning: <basis>/misc/dynamic-wind.sml 16.50.
Sequence expression not of type unit.
type: ['a]
in: cleanup ()
where the Basis Library implementation has:
signature DYNAMIC_WIND =
sig
val wind: (unit -> 'a) * (unit -> unit) -> 'a
end
structure DynamicWind: DYNAMIC_WIND =
struct
fun try (f: unit -> 'a, k: 'a -> 'b, h: exn -> 'b) =
let
datatype t =
A of 'a
| E of exn
in
case A (f ()) handle e => E e of
A a => k a
| E e => h e
end
fun wind (thunk, cleanup) =
try (thunk, fn a => (cleanup (); a), fn e => (cleanup (); raise e))
end
To fix the warning, you need to put a type annotation on cleanup. I think
this behavior is fine, because it would be fairly difficult (I believe) to
distinguish the above case from one where wind was also used within the
structure at non-unit type.