Попытка понять структуру опций 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),

Другие вопросы по тегам