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的创建者都有。谢谢!最终我得到了!