2008-08-30 48 views
18

在StackOveflow中看起來像這裏有一組F#愛好者。F#語言 - 提示新手

我想要更好地瞭解這種語言,因此,除了functional programming theory之外,您能指出我開始使用F#語言的更好的起點嗎?我的意思是,教程,how-tos,但首先工作樣本有機會開始做某件事並享受語言。

非常感謝

安德烈

回答

30

不要可怕的妓女自己,但我寫了一對夫婦的F#概述職位上我的博客herehere。 Chris Smith(MS上F#團隊的成員)在20分鐘內發表了一篇名爲'F#'的文章 - part 1part 2

請注意,由於F#(版本1.9.6.0)的最新CTP與以前版本相比有一些嚴重突破的變化,所以有些示例/教程可能無法修改而無法正常工作。

下面是一些很酷的東西快速破敗,也許我可以在這裏給你一些提示自己這顯然非常簡短,可能不是很大,但希望給你的東西一起玩: - !

首先注意 - 互聯網上的大多數例子都會假設「輕量級語法」處於打開狀態。要做到這一點使用下面的一行代碼: -

#light 

這使您不必插入某些關鍵字是存在於OCaml的兼容性,並且還具有終止與分號每一行。請注意,使用此語法意味着縮進定義範圍。這在後面的例子中將變得清楚,所有這些例子都依賴輕量級語法。

如果您使用的是具有交互模式來終止與雙分號所有語句,例如: -

> #light;; 
    > let f x y = x + y;; 

    val f : int -> int -> int 

    > f 1 2;; 
    val it : int = 3 

需要注意的是交互模式返回每一行後一個「VAL」的結果。這給出了我們正在做的定義的重要信息,例如'val f:int - > int - > int'表示一個帶兩個int的函數返回一個int。

請注意,只有在互動我們需要終止與分號線的時候,居然定義F#代碼,我們可以自由是:-)

你定義使用「讓」關鍵字功能。這可能是所有F#中最重要的關鍵字,您將會使用它很多。例如: - :由空白您可以單獨參數或「元組指定的參數 -

sumStuff 1 2 
3 
sumStuffTuple (1, 2) 
3 

注意這裏有定義函數的兩種不同的方式 -

let sumStuff x y = x + y 
let sumStuffTuple (x, y) = x + y 

我們可以這樣調用這些函數'(即括號中的值由逗號分隔)。不同之處在於,我們可以使用「部分函數應用程序」來獲得使用第一種方法獲取的參數少於所需參數的函數,而不是使用第二種方法。例如: -

let sumStuff1 = sumStuff 1 
sumStuff 2 
3 

注意我們正在從表達式'sumStuff 1'中獲得一個函數。當我們可以像被稱爲具有「頭等功能」的語言那樣簡單地傳遞函數時,這是任何函數式語言(如F#)的基本部分。

模式匹配相當酷,它基本上就像一個關於類固醇的switch語句(是的,我從另一個F#-ist :-)指出了這句話。當我們要匹配的東西,但我們正在返回不依賴於輸入表達式我們使用「_」符號

let someThing x = 
    match x with 
    | 0 -> "zero" 
    | 1 -> "one" 
    | 2 -> "two" 
    | x when x < 0 -> "negative = " + x.ToString() 
    | _ when x%2 = 0 -> "greater than two but even" 
    | _ -> "greater than two but odd" 

注 - :你可以做的東西一樣。

的要求,我們可以縮寫模式使用匹配的,如果,ELIF和else語句: -

let negEvenOdd x = if x < 0 then "neg" elif x % 2 = 0 then "even" else "odd" 

F#列表(被實現爲下面鏈接的列表)可以這樣操作: -

let l1 = [1;2;3] 
l1.[0] 
1 

let l2 = [1 .. 10] 
List.length l2 
10 

let squares = [for i in 1..10 -> i * i] 
squares 
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100] 

let square x = x * x;; 
let squares2 = List.map square [1..10] 
squares2 
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100] 

let evenSquares = List.filter (fun x -> x % 2 = 0) squares 
evenSqares 
[4; 16; 36; 64; 100] 

請注意List.map函數將平方函數映射到從1到10的列表中,即將函數應用於每個元素。 List.filter僅通過返回列表中傳遞提供的謂詞函數的值來「過濾」列表。還要注意'fun x - > f'語法 - 這是F#lambda。

請注意,整個過程中我們還沒有定義任何類型--F#編譯器/解釋器'推斷'類型,即找出你想要的用法。例如: -

let f x = "hi " + x 

這裏的編譯器/解釋器將確定x是一個字符串,因爲你執行這需要X是一個字符串的操作。它也決定了返回類型也是字符串。

在發生模糊的編譯器可以進行假設,例如: -

let f x y = x + y 

這裏x和y可以是多種類型的,但是編譯器默認爲int。如果你要定義你可以使用類型標註類型: -

let f (x:string) y = x + y 

另外請注意,我們不得不附上X:括號中的字符串,我們往往要做到這一點的函數定義的獨立的部分。

F#中兩個真正有用和使用頻率最高的運算符分別是管道前進和函數組合運算符。

我們定義|>這樣的: -

let (|>) x f = f x 

注意,您可以在F#中定義的運營商,這是很酷:-)。

這允許你寫更清晰的事物,e.g.:-

[1..10] |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0) 

將讓您獲得前10個甚至正方形。這是再清楚不過了: -

List.filter (fun x -> x % 2 = 0) (List.map (fun x -> x * x) [1..10]) 

好吧,至少我是這麼認爲的:-)通過>>操作定義

功能組成定義如下: -

let (>>) f g x = g(f(x)) 

即只有第一個功能的參數保持未指定狀態時,纔會對管道進行前進管道操作。這是非常有用的,你可以做到以下幾點: -

let mapFilter = List.map (fun x -> x * x) >> List.filter (fun x -> x % 2 = 0) 

這裏mapFilter將接受一個列表的輸入,並返回作爲過濾前的清單。這是一個精簡版: -

let mapFilter = l |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0) 

如果我們想寫我們通過將「REC」的讓利後定義函數遞歸遞歸函數。下面的例子。

一些很酷的東西: -

階乘

let rec fact x = if x <= 1 then 1 else x * fact (x-1) 

第n個Fibonacci數

let rec fib n = if n <= 1 then n else fib (n-1) + fib (n-2) 

FizzBu​​zz

let (/%) x y = x % y = 0 
let fb = function 
    | x when x /% 15 -> "FizzBuzz" 
    | x when x /% 3 -> "Fizz" 
    | x when x /% 5 -> "Buzz" 
    | x    -> x.ToString() 

[1..100] |> List.map (fb >> printfn "%s") 

無論如何,這是一個非常簡要概述,希望它有一點幫助!

5

毫無疑問,您應該購買Don Syme出色的書籍「Expert F#」。這本書寫得非常好,適合初學者和專家。其中,你會發現介紹材料和更具挑戰性的材料。在近600頁,這是物有所值。

我發現它教會了我很多用於編寫更多功能C#的有用技巧,以及提供開始編寫Windows託管的F#應用程序所需的所有參考資料。

該書由Apress出版出版並且在附帶的網站: http://www.expert-fsharp.com/default.aspx

5

@kronoz - 非常感謝您長時間的回答,這是一個非常好的起點。我會按照你的意見,並尋找提到的書@vecstasy。

現在,讓我去編碼:-)

let thanksalot = "thanks a lot" 
printfn "%s" (thanksalot);; 
+0

upvoted純粹是因爲感謝代碼。呼 - 呀! – AruniRC 2012-05-26 07:26:46

1

如果您在Visual Studio中的當前CTP版本它可以讓你創建一個F#教程項目,它給你一個Tutorial.fs,究竟什麼樣的含這是名字暗示。

該教程還指向F# examples at Microsoft的較大集合。

此外,還有一個F#示例項目正在進行CodePlex

希望這有助於

米希爾

2

我一直在讀Real World Functional Programming

與由F#和C#示例:托馬斯Petricek

到目前爲止,我發現在教學很不錯通過在C#中展示實現來實現F#概念。非常適合OO程序員。

1

我的書F#for Scientists的第一章免費提供here。我們有一系列免費的F#玩具程序here。我們的F#.NET Journal的第一篇文章免費提供here