【问题标题】:SML constantly implementationSML不断实施
【发布时间】:2013-10-29 23:53:15
【问题描述】:

我不断地阅读函数:

fun constantly k a = k

但我不明白如何使用它。 我试过这样:

val a = constantly 10;
stdIn:32.5-32.28 Warning: type vars not generalized because of
  value restriction are instantiated to dummy types (X1,X2,...)
  val a = fn : ?.X1 -> int * int -> int

它是这样工作的:

val a = constantly 10 ();
  val a : int = 10

但不是这样:

val a = constantly 10;
a ();
stdIn:36.1-36.5 Error: operator and operand don't agree [tycon mismatch]
operator domain: ?.X1
operand:         unit
in expression:
  a ()

任何人都可以帮助我理解该功能吗?

【问题讨论】:

    标签: sml currying


    【解决方案1】:

    这是价值限制。理解 ML 中的部分应用很重要。由于存在多态性时的可变性,这是必要的。

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

    任何时候你看到这样的警告,你都可以通过 eta-expanding 表达式来修复它。

    fun a x = constantly 10 x;
    

    【讨论】:

    • 谢谢,有有用的信息,但我不知道它是如何工作的,一直在运行。
    • “由于存在多态性的可变性,这是必要的。”为什么OCaml没有这个问题? OCaml 具有相同的可变性和多态性。但是let constantly k a = k;; let a = constantly 10;; a ();; 在 OCaml 中正确生成 10。
    • OCaml 的创建者有relaxed the value restriction.
    【解决方案2】:

    问题是fun constantly k a = k 的类型为'a -> 'b -> 'a

    constantly 10 这样的部分函数调用将被视为扩展表达式,此时SML 将能够推断constantly 的类型变量的实际类型。也就是说,SML 期望此时它可以将类型变量 'a'b 替换为一些具体类型 T

    由于您的参数 a 未在您的 constantly 函数的主体中使用,因此 SML 无法推断出任何关于它的信息。

    您会期望像 val a = constantly 10 这样的表达式会产生像 'b -> int 这样的类型,但相反,由于 SML 发现它无法确定 'b 的类型,因此它将其更改为虚拟(具体)类型 @987654333 @,这就是为什么你最终会得到一个函数类型?.X1 -> int

    这只是 SML 告诉您它无法正确推断 'b 因为您没有在扩展表达式中为其提供足够的类型信息,因此它为其分配了一个虚拟的具体类型,这基本上使您的功能不可能使用。

    因此,对于另一篇文章中已经提到的解决方案,另一种解决方案是使用具体类型限定生成的函数。

    例如,这应该可以:

    val a = constantly 10: (int -> int)
    

    由于将类型变量'b 限定为int 的明显缺点,因此,柯里化函数a 不再是多态函数,但它确实是柯里化函数。为此,我们需要在创建柯里化函数时知道'b 的具体类型。

    但是,如果您仍然需要 curried 函数是多态的,因为此时您不能假设 'b 的特定/具体类型,那么正如另一个答案提到的那样,您将需要提供另一个带有您的参数的参数多态类型:

    val a = fn x => constantly 10 x
    

    这与 seanmcl 的回答基本相同。

    这会起作用,因为现在x 将在您的调用中携带'b 的具体类型到包装函数中的constantly 10 x。当您调用柯里化函数a 时将定义这种具体类型(即val _ = a(15) 在这种情况下'bint

    【讨论】:

    • 谢谢!终于我明白了!
    猜你喜欢
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    相关资源
    最近更新 更多