2017-08-19 75 views
1

我有以下問題:我通過A.阿佩爾在ML編譯器的工作,我寫了下面的結構簡單SMLNJ - 與聲明類型Typcon不匹配

signature Tiger_Tokens = 
sig 
    type linenum; 
    type token; 
    val ADD : linenum*linenum -> token; 
    val INT : string*linenum*linenum -> token; 
    val EOF : linenum*linenum -> token; 
end 

structure Tokens :> Tiger_Tokens = 
    struct 
     type linenum = int; 
     type token = string 

     fun ADD(i,j) = "ADD" 
     fun INT(number, i, j) = "INT" 
     fun EOF(i,j) = "EOF" 
    end 

使用我編寫本ML-法庫與

type lexresult = Tokens.token 
val lineNum = ref 1; 
fun eof() = Tokens.EOF(!lineNum, !lineNum) 

%% 
digits=[0-9]; 
%% 
\n => (!lineNum = (!lineNum) + 1; lex()); 
"+" => (Tokens.ADD(yypos,yypos+1)); 
{digits}+ => (Tokens.INT(yytext, yypos,yypos+1)); 

,我得到以下錯誤

tiger.lex.sml:172.8-172.33 Error: operator and operand don't agree [tycon mismatch] 
    operator domain: Tokens.linenum * Tokens.linenum 
    operand:   int * int 
    in expression: 
    Tokens.ADD (yypos,yypos + 1) 

現在我清楚已經將類型亞麻布設置爲一個整數。但是當我調用一個需要類型亞型函數(int型)的函數時,我將int作爲參數傳遞(yypos),然後它要求Token.linenum不是int。這不是一個整數,因爲我把它設置爲這樣?或者SML將這些視爲不同的類型。如果他們確實將它們視爲不同類型,那麼除了命名「特殊」類型的int類型之外,類型聲明的要點是什麼?

在此先感謝。

回答

0

所以我正在執行的解決方案是在簽名中聲明類型。換句話說

signature Tiger_Tokens = 
sig 
    type linenum = int; 
    type token; 
    val ADD : linenum*linenum -> token; 
    val INT : string*linenum*linenum -> token; 
    val EOF : linenum*linenum -> token; 
end 

但你仍然需要一點redundency的,你還是要重新聲明它在你的結構。希望這可以幫助別人!

2

的問題是你有簽名的歸屬,即:>部分:

structure Tokens :> Tiger_Tokens = 

這樣做有什麼有效地隱藏所有類型的Tokens。它被稱爲不透明簽名歸屬。

還有另一種形式的實際上將暴露所有類型:一透明簽名歸屬:

structure Tokens : Tiger_Tokens = 

的中間地帶被稱爲半透明簽名的歸屬和是這樣的:

structure Tokens :> Tiger_Tokens where type linenum = int = 

這隻公開linenum類型,而token仍然是抽象的。

+0

非常感謝。 – Freddie