F#中的价值限制案例

时间:2012-07-29 13:36:03

标签: f#

我很困惑为什么第三个功能不起作用:

   let generate1 = id
   let generate2 = let a = 1
                   id
   let generate3 = printfn "hi"
                   id

虽然前2个很好,但最后一个吐出

error FS0030: Value restriction. The value 'generate3' has been inferred to have generic type
    val generate3 : ('_a -> '_a)    
Either make the arguments to 'generate3' explicit or, if you do not intend for it to be generic, add a type annotation.

1 个答案:

答案 0 :(得分:6)

我不会尝试explain value restriction,但我会尝试理清这三个值之间的语义差异。

generate1只是id的别名,所以我们在那里很好。

generate3在返回id之前会进行一些计算,达到值限制。

那么为什么generate2不会像generate3那样达到价值限制?因为编译器可以看到let x = 1 in id在语义上等同于id1是一个常量表达式而x未在let ... in ...表达式的主体中使用,所以编译器可以并且确实将它们抛弃了。另一方面,如果将1替换为潜在的副作用,如sin 2.3sin是纯粹的,但编译器无法证明它),那么编译器无法安全地减少表达式,因此与generate3一样达到了值限制。