Глядя на 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
, и если он не может это выяснить, он выдает ошибку «неразрешенная запись».