Попытка понять структуру опций SML
Итак, я начал изучать SML для класса, и я застрял с опционной структурой. Что я пока имею для этого примера:
datatype suit = spades|hearts|clubs|diamonds;
datatype rank = ace|two|three|...|j|q|k|joker;
type card = suit*rank;
Мой лектор пытался объяснить использование структуры опций, сказав, что не все карты обязательно имеют масть; у джокеров нет костюма, связанного с ними. Поэтому, когда мы создаем набор функций для получения масти карты, мы имеем следующее:
datatype 'a option = NONE | SOME of 'a;
fun getsuit ((joker,_):card):suit option = NONE
| getsuit ((_,s):card):suit option = SOME s;
Но используя emacs, я получаю две ошибки, одна из которых говорит о том, что шаблон и ограничение не согласуются,
pattern: rank * ?.suit
constraint: rank * suit
а другой говорит, что тип выражения и результирующие типы не совпадают.
expression: ?.suit option
result type: suit option
Это был код, предоставленный лектором, поэтому они явно не сильно помогают, если это приводит к ошибкам. Что значит "?." и почему это появляется? Как бы я правильно определил эту функцию?
1 ответ
Не совсем проблема с option
как вы определили. У вас есть заказ suit
а также rank
в вашем card
шаблоны неправильный путь:
Пытаться:
datatype 'a option = NONE | SOME of 'a;
fun getsuit ((_, joker):card):suit option = NONE
| getsuit ((s, _):card):suit option = SOME s;
Моя версия ML, вероятно, печатает ошибки по-другому, поэтому я не знаю, как объяснить значение ?.
и т.д. Но это достаточно просто, если вы берете это по крупицам:
Пытаться
(clubs, ace);
Интерпретатор (или emacs, если это то, что вы используете) говорит вам, что тип является продуктом suit * rank
, Это вывод типа ML на работе, но вы можете указать тип (как вы ожидаете) следующим образом:
(clubs, ace): suit*rank;
Или же
(clubs, ace): card; (* Works, since card is defined as (suit*rank) *)
И у вас не будет никаких жалоб. Но, очевидно, вы бы, если бы вы сделали
(clubs, ace): rank*suit;
Или же
(clubs, ace): card; (* card is defined as (rank*) *)
Вы установили ограничение на тип getsuit
аргумент (что это должно быть card
или совместимый (suit*rank)
продукт), но шаблон имеет тип (rank*?)
или же (?*rank)
, ни один из которых не совместим с (suit*rank)
,