2013-01-15 31 views
2

好吧,所以我开始为一个类学习SML,并且我坚持使用选项结构。 我至今这个例子是什么:试图了解SML选项结构

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

我的讲师试图通过说,并非所有的卡一定西装解释如何使用选项结构; jokers没有与他们相关的诉讼。 因此设计一个功能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 

这是由讲师提供的代码,以便他们显然是有很大帮助,如果没有它会导致错误。 “?”的含义是什么?为什么会出现?我将如何正确定义这个功能?

回答

5

如您所定义的那样,option并非真正的问题。 你已经有了一个suitrank的顺序,你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)兼容。

+0

谢谢,这很简单,我不知道我怎么没有抓住它之前。我尝试了你的第一个建议,它工作正常!谢谢! – quitquit