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?
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 thatais a pair.While you could resolve this just by giving
aa type declaration, the nicer way of doing it is to pattern-match it. Instead of defining you argument as(a,b)and using#1aand#2a, define your argument as((x,y),b)and usexandy.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 tofoldlshould befn ((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 returnSo when you say
#1a, you’re really saying “extract the element with the label1from the recorda“.SML/NJ has no concept of record polymorphism. It understands that
amust be a record, and that this record type must at least contain the label1(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.