2012-03-23 3 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}에 대해 과 동일하게입니다. 당신은 SML/NJ 쉘에 {1=1,2=2}를 입력하면 그리고 사실, 그것은 당신이 #1a을 말할 때, 당신이 정말로 "기록 a에서 레이블 1와 요소를 추출"말을하는지 그래서

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

를 반환합니다.

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