2010-12-08 34 views

回答

3

Scheme是一個很好的函數式語言;在學校學習應該爲功能編程提供良好的基礎。

F#是靜態類型的,而Scheme是動態的,所以這是一個明顯的區別。如果您有其他靜態語言(尤其是C#等.NET語言)的使用經驗,那麼這並不是什麼大不了的事情,但如果您的大部分經驗都是動態的,那將是一個改變。學習主要F#函數編程函數的名稱(例如List.map)很重要;大多數每種功能語言都有相同的基本設置,但通常名稱不同(我不記得要比較的主要計劃名稱)。

如果您有方便的樣本輸入/輸出的舊程序'編程任務',可能有必要在F#中對它們進行重新編碼,作爲用語言「預熱」的一種方式。

5

在學習F#的時候,我有什麼需要記住的嗎?方法,陷阱或其他可能給我帶來麻煩的任何差異?

靜態分型是Scheme和F#之間的主要區別。這有利於一種稱爲類型編程的風格,其中類型系統用於對關於函數和數據的約束進行編碼,以便編譯器在編譯時證明程序的這些方面是正確的,並且立即捕獲任何違反約束的情況。

例如,相同類型的一個或多個元素的序列可能是由以下類型的值傳送:

type list1<'a> = List1 of 'a * 'a list 

let xs = List1(1, []) 
let ys = List1(2, [3; 4]) 

編譯器現在保證了任何企圖利用的這些空單序列將在編譯時被捕獲爲錯誤。現在

,該reduce功能使得在一個空的順序沒有任何意義,因此內置實施名單barfs在運行時有異常,如果它遇到一個空序列:

> List.reduce (+) [];; 
System.ArgumentException: The input list was empty. 
Parameter name: list 
    at Microsoft.FSharp.Collections.ListModule.Reduce[T](FSharpFunc`2 reduction, FSharpList`1 list) 
    at <StartupCode$FSI_0271>[email protected]() 
Stopped due to error 

隨着我們的新序列一個或多個元素,我們現在可以編寫一個reduce功能,從來沒有因爲它的輸入由類型系統保證爲非空的,一個例外,在運行時barfs:

let rec reduce f = function 
    | List1(x, []) -> x 
    | List1(x0, x1::xs) -> f x0 (reduce f (List1(x1, xs))) 

這是一個偉大的方式改善可靠性通過消除運行時錯誤的來源,這是一種動態類型語言,例如Scheme甚至無法做到的事情。

+0

感謝您的徹底回覆!我對第一個代碼示例有點不清楚,你能否澄清一下這是做什麼的。 – 2010-12-09 19:21:07

1

我建議你也考慮Haskell,它們和F#和ML大致在同一個家族,而Haskell包含了很多其他地方沒有的有趣的功能概念。

查看tryhaskell.org以獲取交互式在線教程。