2013-01-15 32 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