The binding patterns that select record fields introduce ambiguities
that usually need some kind of explicit type constraint.
type Cmd = {
name: string,
data: int
}
fun show {name, ...} = print name
fun process cmd = print(#name cmd)
fun size ({data, ...}: Cmd) = data |
rec1.sml:6.1-6.34 Error: unresolved flex record
(can't tell what fields there are besides #name)
type4a.sml:8.1-8.35 Error: unresolved flex record
(can't tell what fields there are besides #name) |
The binding pattern in show is called a "flex record". It can match
against any record type that contains a field called name. But you
aren't allowed to make a function polymorphic over all such record types
so you have to constrain its type as done in the size function.
The field selector #name is equivalent to the function (fn
{name, ...} => name) so it has the same problem.
I prefer to use a datatype for all record types. The constructor will
serve to constrain the type.
datatype Cmd = Cmd of {
name: string,
data: int
}
fun show (Cmd {name, ...}) = name |