В SML тип списка записывается как elementType list
, а не [elementType]
. Таким образом, тип списка int-троек равен (int*int*int) list
, а не [int*int*int]
.
Поэтому, когда SML видит [
, он думает, что видит начало шаблона (в частности, шаблона списка), а не типа. Это заставляет думать, что :
неверно (поскольку за :
должен следовать тип), и алгоритм восстановления после ошибки заменяет его на as
, потому что это будет допустимо между идентификатором и шаблоном.
А что на земле есть КАК?
Это ключевое слово, используемое в сопоставлении с образцом для присвоения имени результату сопоставления с образцом. Например, если вы хотите сопоставить трехэлементный список с шаблоном списка, но вам также нужно имя для всего списка, вы можете написать fun number_in_month (date as [x1, x2, x3]) = ...
. В этом случае три элемента списка будут известны как x1
, x2
и x3
соответственно, а весь список будет известен как date
.
Теперь нет причины, по которой вы хотите использовать здесь ключевое слово as
. Так получилось, что парсер придумал, потому что fun number_in_month (date as [
может быть началом синтаксически правильной программы, но fun number_in_month (date : [
не может быть.
Итак, ваша фиксированная подпись должна выглядеть так:
number_in_month (date : (int*int*int) list, month : int) : int =
Теперь вы получите кучу ошибок типов в теле функции, связанных с некоторыми пропущенными скобками (например, #2 hd date
эквивалентно неверно набранному (#2 hd) date
, а не #2 (hd date)
, что вам и нужно хотите) и тот факт, что number_in_month
принимает два аргумента, а не один (другими словами: вы пропускаете аргумент date
при рекурсивном вызове number_in_month
).