问题
I've come across a tuples problem where given a list of pair tuples it should become a pair of lists: i.e. [(1,2),(3,4),(5,6)]
should return ([1,3,5],[2,4,6])
.
I've tried to solve it using this code:
fun convert L = foldl (fn(a,b) => #1a::b) [] L;
But I get an error saying: unresolved flex record. Anyone able to explain why I'm getting this and how it could be fixed?
回答1:
Looking at a
, the compiler can tell it's supposed to be a tuple (since you're calling #1a
), but it can't tell how big it is. The SML type system doesn't allow tuples of unknown size; you need to make it clear that a
is a pair.
While you could resolve this just by giving a
a type declaration, the nicer way of doing it is to pattern-match it. Instead of defining you argument as (a,b)
and using #1a
and #2a
, define your argument as ((x,y),b)
and use x
and y
.
There's another issue with your solution, however. Your function is adding the first element of the pair to a result list, but you're ignoring the second element (#2a
), and your result lacks a second list. The function you're passing to foldl
should be fn ((x,y),(u,v)) => ...
, and your initial value should be ([],[])
.
The reason for that cryptic error message, "unresolved flex record", is that tuples in SML are implemented as records with integer labels. The tuple (a,b)
is identical to the record {1=a,2=b}
. And in fact, if you type {1=1,2=2}
into the SML/NJ shell, it will return
val it = (1,2) : int * int
So when you say #1a
, you're really saying "extract the element with the label 1
from the record a
".
SML/NJ has no concept of record polymorphism. It understands that a
must be a record, and that this record type must at least contain the label 1
(and potentially others), but there's no way to express this in the SML/NJ type system.
So the compiler needs to know the exact structure of the record in order to infer a type for a
, and if it can't figure it out, it throws an "unresolved record" error.
回答2:
I don't have an SML interpreter handy, but I think that you are looking for unzip. Try:
unzip([(1,2), (3,4), (5,6)]);
IIRC, "unresolved flex record" had to do with record matching which you aren't using here?! Take a look at the error docs for smlnj (http://www.smlnj.org/doc/errors.html). You will need to search for error [99]
near the bottom.
回答3:
- ListPair.unzip([(1,2), (3,4), (5,6)]);
> val it = ([1, 3, 5], [2, 4, 6]) : int list * int list
来源:https://stackoverflow.com/questions/9845654/sml-tuples-combination