Кортежи SML - комбинация - PullRequest
1 голос
/ 23 марта 2012

Я столкнулся с проблемой кортежей, когда при наличии списка парных кортежей он должен стать парой списков: т.е.

Я пытался решить эту проблему с помощью этого кода:

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

Но я получаю сообщение об ошибке: неразрешенная гибкая запись. Кто-нибудь может объяснить, почему я получаю это и как это можно исправить?

Ответы [ 3 ]

3 голосов
/ 24 марта 2012

Глядя на a, компилятор может сказать, что он должен быть кортежем (поскольку вы вызываете #1a), но он не может сказать, насколько он велик. Система типов SML не допускает кортежи неизвестного размера; вам нужно прояснить, что a - это пара.

Хотя вы можете решить эту проблему, просто указав a объявление типа, лучший способ сделать это - сопоставить его с шаблоном. Вместо того, чтобы определять ваш аргумент как (a,b) и использовать #1a и #2a, определите ваш аргумент как ((x,y),b) и используйте x и y.

Однако в вашем решении есть еще одна проблема. Ваша функция добавляет первый элемент пары в список результатов, но вы игнорируете второй элемент (#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, вы действительно говорите: «Извлеките элемент с меткой 1 из записи a».

SML / NJ не имеет понятия рекордного полиморфизма . Он понимает, что a должна быть записью и что этот тип записи должен по крайней мере содержать метку 1 (и, возможно, другие), но нет способа выразить это в системе типов SML / NJ.

Таким образом, компилятору нужно знать точную структуру записи, чтобы вывести тип для a, и если он не может это выяснить, он выдает ошибку «неразрешенная запись».

0 голосов
/ 01 марта 2016
- ListPair.unzip([(1,2), (3,4), (5,6)]);
> val it = ([1, 3, 5], [2, 4, 6]) : int list * int list
0 голосов
/ 24 марта 2012

У меня нет удобного переводчика SML, но я думаю, что вы ищете unzip. Попробуйте:

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

IIRC, "неразрешенная гибкая запись" имела отношение к сопоставлению записей, которое вы здесь не используете ?! Посмотрите на документацию об ошибках для smlnj (http://www.smlnj.org/doc/errors.html). Вам нужно будет найти ошибку [99] в нижней части.

...