SML 警告 : Type Vars Not Generalized when using Empty Lists or NONE option

标签 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;

每当我使用以下测试函数调用 my_func 时:
my_func f [NONE, NONE];
my_func f [];

我总是收到警告:

Warning: type vars not generalized because of value restriction are instantiated to dummy types (X1,X2,...)



每当我传入包含至少一个 SOME 值的选项列表时,都不会抛出此警告。我知道这一定与我在函数柯里化(Currying)中使用多态性这一事实有关,但我完全不知道如何摆脱这些警告。

如果您有任何想法,请提供帮助 - 在此先感谢您!

最佳答案

警告中引用的值限制是在 SML 中更难理解的事情之一,但是我会尽力解释为什么会在这种情况下出现,并尝试向您指出一些资源以了解更多信息。

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

myfunc f [NONE, SOME 1, NONE];

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

但是,当您在没有诸如 SOME 1 之类的值的情况下调用它时多于
myfunc f [NONE, NONE];

你认为类型变量应该被实例化成什么?类型应该是多态的——类似于 't option't适用于所有类型 't .但是,有一个限制可以防止像这样的值采用多态类型。

SML 将一些表达式定义为非扩展值,并且只有这些值可以采用多态类型。他们是:
  • 文字(常量)
  • 变量
  • 函数表达式
  • 构造函数(除了 ref )应用于非扩展值
  • 带有类型注释的非扩展值
  • 每个字段都是非扩展值的元组
  • 每个字段都是非扩展值的记录
  • 列出每个字段都是非扩展值

  • 所有其他表达式,特别是函数调用(这是对 my_func 的调用)不能是多态的 .也不能引用。您可能会好奇地看到以下内容不会引发警告:
     fn () => my_func f [NONE, NONE];
    

    相反,推断的类型是 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)
    

    由于值限制,此程序不会在 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

    关于SML 警告 : Type Vars Not Generalized when using Empty Lists or NONE option,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14668433/

    相关文章:

    algorithm - 整数 数字的平方根

    sml - 处理不属于数据类型的变量

    list - SML - 查找列表中的出现次数以形成有序对

    ocaml - ML 系列编译器是否对尾调用进行了任何复杂的优化?

    recursion - 用函数式语言实现快速排序

    objective-c - Objective C 中的惰性数据类型

    SML/NJ 基础库无法在 Windows 10 中运行

    types - 在SML的这段代码中 “node”在做什么?

    sml - 问ML递归函数

    functional-programming - SML Ml 编程函数是具有 bool 条件的旧日期