2012-05-04 192 views
0

我目前在學習SML,並且對於我沒有名字的東西有疑問。現在讓我們稱之爲「輸入別名」。假設我有以下數據類型定義:SML中的類型推斷

datatype 'a stack = Stack of 'a list; 

我現在想添加一個明確的「空棧」類型。我可以這樣將它添加到數據類型:

datatype 'a stack = emptystack | Stack of 'a list; 

現在我可以匹配模式像「推送」功能:

fun push (emptystack) (e:'a) = Stack([e]) 
    | push (Stack(list):'a stack) (e:'a) = Stack(e::list); 

這裏的問題是,Stack([])emptystack是不同的,但我想他們是一樣的。因此,每當SML遇到Stack([])時,它應該「知道」這是emptystack(在推送的情況下它應該使用空堆匹配)。

有沒有辦法做到這一點?

+1

只是爲了記錄,它被稱爲*推理*,而不是*干擾*。 SML編譯器*推斷*表達式的類型。它不*干擾* :) – jalf

+2

這引發了一個問題:*爲什麼*你甚至想要這樣做?第二版「棧」比第一版更受歡迎?通常,人們想要刪除多餘的案例,而不是引入它們。 –

回答

1

簡短的回答是:不,這是不可能的。

您可以創建類型別名的代碼

type number = int 

val foo : number -> int -> number = 
fn a => fn b => a+b 

val x : int = foo 1 3; 
val y : number = foo 1 3; 

然而,正如它的名字說,它僅適用於類型。你的問題是價值構造函數,沒有語法。

1

這種混疊在SML中是不可能的。相反,你應該設計你的數據類型在它們的表示中是明確的,如果這是你想要的。

你可能更適合的東西,酷似'a list更多的定義:

datatype 'a stack = EmptyStack | Stack of 'a * 'a stack; 

這有沒有讓你使用它的列表功能的缺點,但你得到一個明確的空堆棧構造函數。

0

既然你想要的是一個值emptystack是另一個值Stack []的代名詞,你可以打電話給你正在尋找「價值別名」。與內置運算符=或模式匹配進行比較的值將不允許使用別名。

您可以通過創建您自己的相等運算符來實現此目的,但您將失去使用內置=(因爲Standard ML不支持自定義運算符重載)的能力以及對值進行模式匹配的功能你的類型的構造函數。

或者,您可以爲您的類型構造一個正常形式,並且始終比較正常形式。只要切實可行,請按照塞巴斯蒂安的建議,即不含糊。在這種情況下,明確的代數類型比簡單的代數類型複雜得多,它允許以不同的方式表示相同的值。