2012-03-23 67 views
1

我碰到一個元組問題,其中給出了一對元組列表,它應該成爲一對列表:即[(1,2),(3,4),(5,6)]應該返回([1,3,5],[2,4,6])SML元組 - 組合

我嘗試使用此代碼來解決這個問題:

fun convert L = foldl (fn(a,b) => #1a::b) [] L; 

,但我得到一個錯誤說:無法解析的柔性紀錄。 任何人都能解釋爲什麼我得到這個以及它如何被修復?

回答

3

看着a,編譯器可以告訴它應該是一個元組(因爲你叫#1a),但它不能說明它有多大。 SML類型系統不允許未知大小的元組;你需要明確說明a是一對。

雖然你可以通過給a一個類型聲明來解決這個問題,但更好的方法是模式匹配它。不要將您的參數定義爲(a,b)並使用#1a#2a,請將您的參數定義爲((x,y),b),並使用xy

但是,解決方案存在另一個問題。您的函數將該對的第一個元素添加到結果列表中,但是您忽略了第二個元素(#2a),並且結果中沒有第二個列表。你傳遞給foldl的函數應該是fn ((x,y),(u,v)) => ...,你的初始值應該是([],[])


的原因是什麼神祕的錯誤消息,「未解決的柔性記錄」,是在SML元組與整數標籤記錄來實現。元組(a,b)相同的到記錄{1=a,2=b}。而事實上,如果你輸入{1=1,2=2}到SML/NJ外殼,它會返回

val it = (1,2) : int * int 

所以,當你說#1a,你真的說:「從記錄a標籤1提取元素」。

SML/NJ沒有record polymorphism的概念。它理解a必須是記錄,並且此記錄類型必須至少包含標籤1(可能還有其他人),但是在SML/NJ類型系統中無法表達這一點。

因此,編譯器需要知道記錄的確切結構,以便推斷出a的類型,如果無法找出它,則會拋出「未解決的記錄」錯誤。

0

我沒有SML解釋器,但我認爲您正在尋找unzip。嘗試:

unzip([(1,2), (3,4), (5,6)]); 

IIRC,「未解決的彈性記錄」必須處理記錄匹配,你不使用這裏?!查看smlnj的錯誤文檔(http://www.smlnj.org/doc/errors.html)。您需要在底部附近搜索錯誤[99]

0
- ListPair.unzip([(1,2), (3,4), (5,6)]); 
> val it = ([1, 3, 5], [2, 4, 6]) : int list * int list