Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Types SMLNJ-Typcon与声明的类型不匹配_Types_Sml_Lex - Fatal编程技术网

Types SMLNJ-Typcon与声明的类型不匹配

Types SMLNJ-Typcon与声明的类型不匹配,types,sml,lex,Types,Sml,Lex,我有以下问题:我正在用ML处理A.Appel的编译器,我已经编写了以下简单的结构 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 stru

我有以下问题:我正在用ML处理A.Appel的编译器,我已经编写了以下简单的结构

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 lex库编译此文件

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)
现在很明显,我已经将类型linenum设置为int。但是当我调用一个需要类型linenum(即int)的函数时,我将int作为参数传递(yypos),然后它会请求Token.linenum而不是int。这不是一个int,因为我将它设置为int吗?或者SML将这些视为不同的类型。如果他们确实将它们视为不同的类型,那么除了命名“特殊”类型的int之外,类型声明还有什么意义呢


提前感谢。

所以我实现的解决方案是在签名中声明类型。换句话说

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

但是你仍然需要一些冗余,你仍然需要在你的结构中重新声明它。希望这对别人有帮助

问题在于您拥有的签名归属,即
:>
部分:

structure Tokens :> Tiger_Tokens =
这样做的目的是有效地隐藏
标记中的所有类型。这叫做不透明的签名归属

还有另一种形式将实际公开所有类型:透明签名归属:

structure Tokens : Tiger_Tokens =
中间地带称为半透明签名归属,如下所示:

structure Tokens :> Tiger_Tokens where type linenum = int =

这只公开了
linenum
类型,而
token
仍然是抽象的。

非常感谢。