SML tuples - Combination

三世轮回 提交于 2019-12-13 17:58:09

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!