SML的持续实施

SML的持续实施,sml,currying,Sml,Currying,我经常读到关于函数的内容: 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 ->

我经常读到关于函数的内容:

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 ()
它是这样工作的:

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 ()
但并非如此:

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 ()

有人能帮我理解这个函数吗?

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

任何时候看到这样的警告,都可以通过扩展表达式来修复

fun a x = constantly 10 x;

问题是,ka=k具有类型
'a->'b->'a

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

由于参数
a
未在
函数体中经常使用,因此SML无法对其进行任何推断

您可能希望像
val a=10
这样的表达式会产生像
'b->int
这样的类型,但是相反,因为SML发现它无法确定
'b
的类型,所以它将其更改为伪(具体)类型
?.X1
,这就是为什么最终得到的是函数类型
?.X1->

这只是SML告诉您,它不能正确地推断出
'b
,因为您在扩展表达式中没有为它提供足够的类型信息,因此它为它指定了一个伪具体类型,这基本上使您的函数无法使用

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

例如,这应该是可行的:

val a = constantly 10: (int -> int)
由于将类型变量
'b
限定为
int
,因此,curried函数
a
不再是多态函数,而是一个curried函数。为了实现这一点,我们需要知道在创建curried函数时
'b
的具体类型

但是,如果您仍然需要curried函数是多态的,因为此时无法假定
'b
的特定/具体类型,那么,正如其他答案所述,您需要提供另一个带有多态类型的参数:

val a = fn x => constantly 10 x
这与seanmcl的答案基本相同


这将起作用,因为现在
x
将在调用包装函数的
过程中携带
'b
的具体类型。这种具体类型将在您调用当前函数
a
(即
val=a(15)
时定义。在本例中,
'b
int

谢谢,有一些有用的信息,但我无法了解它是如何工作的,经常运行的。“这是必要的,因为多态性的存在是可变的。”为什么OCaml没有这个问题?OCaml具有相同的易变性和多态性。但是
让k a=k;;设a=10;;a()在OCaml中正确生成10个。似乎OCaml的创建者都有。谢谢!最终我得到了!