F#中的价值限制案例

nic*_*las 1 f#

我很困惑为什么第三个函数不起作用:

   let generate1 = id
   let generate2 = let a = 1
                   id
   let generate3 = printfn "hi"
                   id
Run Code Online (Sandbox Code Playgroud)

而前两个很好,最后一个吐出来

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.
Run Code Online (Sandbox Code Playgroud)

Ste*_*sen 6

我不会试图解释价值限制,但我会尝试理清这三个值之间的语义差异.

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

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

那为什么不generate2打价值限制generate3呢?因为编译器可以看到它let x = 1 in id在语义上等同于id:1是一个常量表达式而x不是在let ... in ...表达式的主体中使用,所以编译器可以并且确实将它们抛弃了.的On-the-另一手,如果更换1与像一个潜在的副作用sin 2.3(sin是纯粹的,但是编译器不能证明这一点),那么编译器不能安全地减少的表达,从而创下值的限制与generate3.