2013-11-21 74 views
1

以下是我在F#編輯器中編寫的函數,它按照我的預期工作(答案:18)。關於F#函數

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 

我越來越「值或構造‘quadrule’沒有定義」。從錯誤中,我認爲,失敗是由於聲明之前的函數調用。對我來說,它就像一個口譯員風格。

問題:爲什麼這樣的限制?這是否有意保持一些兼容性問題?還是因爲我沒有定義任何模塊/類?

+4

在F#中,編譯和定義順序**很重要**。我不知道這是什麼原因(可能類型推斷沒有它,或者效果不好),但是函數/模塊必須被定義爲'在'任何其他功能和/或使用它們的模塊之上'。完整的文件也必須移動到其他可能引用它們的文件之上。 –

+0

@PatrykĆwiek,感謝您的評論。 – Nair

+1

@Nair:讓你的依賴以代碼和項目結構爲模型是件好事。在C#中,管理相互依賴關係要困難得多,特別是對於大型項目。 – Daniel

回答

2

儘管慣用代碼中需要最少量的類型聲明,但F#卻是一種靜態強類型語言。這是可能的,因爲編譯器能夠推斷可以完成的類型明確通過被稱爲type inference的過程。

簡單地說,類型推斷在F#中工作的處理方向是在代碼上從左到右的一個傳遞。此因素影響定義的內部和文件間放置以及F#代碼元素的使用。

將此原則應用於第二個片段:當編譯器首次在第一行中出現quadruple時,根據迄今分析的信息解析該元素的類型,此元素的類型並不知道;這就是錯誤信息的通信。

注:沒有從這一原則在有關OOP,其中定義之前的使用是允許在一定程度上,像Code財產的使用在Sample類方法Double()下面,在那裏F#的面積一定的偏差在屬性定義之前使用:

type Sample() = 
    member this.Double() = this.Code * 2 
    member this.Code with get() : int = 3 

用於在類型推斷運作細粒的細節最好的地方是檢查F# Language Specification