我不能为我的生活弄清楚为什么以下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 option和int.
然而,当你不使用一个值,如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
| 归档时间: |
|
| 查看次数: |
4074 次 |
| 最近记录: |