2

好的,所以我开始为一堂课学习 SML,但我坚持使用选项结构。到目前为止,我对这个例子有什么:

datatype suit = spades|hearts|clubs|diamonds;
datatype rank = ace|two|three|...|j|q|k|joker;
type card = suit*rank;

我的讲师试图解释期权结构的使用,他说并非所有的牌都一定有花色。小丑没有与之相关的西装。所以在设计一个函数getsuit来得到一张牌的花色时,我们有以下几点:

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

这是讲师提供的代码,很明显,如果它导致错误,它们并没有多大帮助。“?”是什么意思。为什么会出现?我将如何正确定义此功能?

4

1 回答 1

5

option正如您定义的那样,这并不是真正的问题。您的模式顺序suit和模式错误:rankcard

尝试:

datatype 'a option = NONE | SOME of 'a;

fun getsuit ((_, joker):card):suit option = NONE
  | getsuit ((s, _):card):suit option = SOME s;

我的 ML 版本可能会以不同的方式打印错误,所以我不确定如何解释?.etc 的含义。但如果你一点一点理解它就足够简单了:

尝试

(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的参数类型设置了约束(它必须是 acard或兼容的(suit*rank)产品),但模式的类型是(rank*?)or (?*rank),两者都不兼容(suit*rank)

于 2013-01-15T20:46:29.007 回答