SML警告:使用空列表或NONE选项时,键入Vars Not Generalized

mbe*_*ear 11 sml smlnj

我不能为我的生活弄清楚为什么以下SML功能在我的作业问题中抛出警告:

fun my_func f ls  = 
  case ls of 
  [] => raise MyException
  | head :: rest => case f head of 
                    SOME v => v
                    | NONE => my_func f rest

fun f a = if isSome a then a else NONE;
Run Code Online (Sandbox Code Playgroud)

每当我使用以下测试函数调用my_func时:

my_func f [NONE, NONE];
my_func f [];
Run Code Online (Sandbox Code Playgroud)

我总是收到警告:

警告:由于值限制而未通用的类型变量被实例化为虚拟类型(X1,X2,...)

每当我传入包含至少一个SOME值的选项列表时,都不会抛出此警告.我知道它必须与我在函数currying中使用多态的事实有关,但我已经完全陷入了如何摆脱这些警告.

如果您有任何想法请帮助 - 提前谢谢!

mic*_*kig 20

警告中引用的值限制是SML中需要理解的棘手问题之一,但是我会尽力解释为什么它会出现在这种情况下,并尝试指向一些资源以了解更多信息.

如您所知,SML将使用类型推断来推断程序中的大多数类型.在这个程序中,my_func将推断出类型('a -> 'b option) -> 'a list -> 'b.如你所知,它是一种多态类型.当你调用my_func这样

myfunc f [NONE, SOME 1, NONE];
Run Code Online (Sandbox Code Playgroud)

...类型变量'a'b实例化为int optionint.

然而,当你不使用一个值,如SOME 1以上

myfunc f [NONE, NONE];
Run Code Online (Sandbox Code Playgroud)

您认为应该将类型变量实例化为什么?该类型应该是多态的-像't option't所有类型't.但是,有一个限制可以阻止这样的值采用多态类型.

SML将一些表达式定义为非扩展值,只有这些值可以采用多态类型.他们是:

  • 文字(常数)
  • 变量
  • 函数表达式
  • 构造函数(除外ref)适用于非扩展值
  • 带有类型注释的非扩展值
  • 每个字段都是非扩展值的元组
  • 记录每个字段是非扩展值的位置
  • 列出每个字段是非扩展值的位置

所有其他表达式,特别是函数调用(调用的my_func是)不能是多态的.两者都没有引用.您可能很想知道以下内容未发出警告:

 fn () => my_func f [NONE, NONE];
Run Code Online (Sandbox Code Playgroud)

相反,推断的类型是unit -> 'a.但是,如果您要调用此函数,则会再次收到警告.

我对这种限制的原因的理解有点弱,但我认为潜在的根本问题是可变引用.以下是我从以下链接的MLton网站获取的示例:

val r: 'a option ref = ref NONE
val r1: string option ref = r
val r2: int option ref = r
val () = r1 := SOME "foo"
val v: int = valOf (!r2)
Run Code Online (Sandbox Code Playgroud)

由于价值限制,该程序在SML下没有进行类型检查.如果不是值限制,该程序在运行时会出现类型错误.

正如我所说,我的理解是不稳定的.但是我希望我对你遇到的问题略有说明,虽然我相信在你的情况下你可以安全地忽略警告.如果您决定深入挖掘,请参考以下内容:

http://users.cis.fiu.edu/~smithg/cop4555/valrestr.html

http://mlton.org/ValueRestriction

(顺便说一句的MLton网站是纯金的.有这么多隐藏掉在这里,所以如果你想了解关于SML奇怪的东西,我强烈建议在这里寻找,因为你很可能会转起来比你最初想了很多)

由于您似乎实际上正在使用SML/NJ,因此这是一个非常方便的错误消息和警告指南,它将在编译时为您提供:

http://flint.cs.yale.edu/cs421/smlnj/doc/errors.html