以下是我在F#编辑器中编写的函数,它按预期工作(答案:18)。
let quadruple x = x*2
let cal(u:int) = quadruple u + 10;
let result = cal 4
但是如果我改变了代码的顺序,比如
let cal(u:int) = quadruple u + 10;
let quadruple x = x*2
let result = cal 4
我得到“未定义的值或构造函数'四元组'”。从错误来看,我认为,失败是由于函数调用之前的声明。对我来说,这就像翻译风格。
问题:为何会出现此类限制?有目的地保持一些兼容性问题吗?或者是因为我没有定义任何模块/类?
答案 0 :(得分:2)
尽管在惯用代码中需要最少量的声明类型,但F#是一种静态强类型语言。这是可能的,因为编译器能够通过称为type inference的过程推断出可以明确的类型。
简单地说,类型推断在F#中工作的处理方向是在代码上从左到右自上而下的一次传递。此因素会影响定义的文件内和文件间放置以及F#代码元素的使用。
将这个原则应用到你的第二个片段:当编译器在第一行中第一次出现quadruple
时,基于迄今为止解析的信息,这个元素的类型没有任何已知信息可以消除歧义;这就是错误信息传达的内容。
注意:在与OOP相关的F#区域中存在一定的偏离,其中允许在定义之前使用某种程度,例如在{0}中使用Code
属性下面的Sample
类方法Double()
,在属性定义之前使用它:
type Sample() =
member this.Double() = this.Code * 2
member this.Code with get() : int = 3
对于类型推断工作的细粒度细节,最好检查的地方是F# Language Specification。