成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

F#入門:基本語法,模式匹配及List

開發(fā) 后端
F#是隨著VS2010 Beta版一起正式推出的另一個基于.NET平臺的語言,以函數(shù)式語言著稱。這個F#入門文章介紹了F#的基本語法,模式匹配及List基本類型。

F#隨著VSTS 2010 Beta1 發(fā)布也有一段時間了,園子里應該也有不少人對它感興趣吧。下面的例子是我在學F# 基本語法時寫的一個簡單Sieve of Eratosthenes 實現(xiàn),通過剖析這一小段代碼,我希望大家能對F#有個簡單認識,并能自己寫一些簡單的小程序。

F#入門代碼

  1. let GetAllPrimesBefore n =   
  2.     let container = Array.create (n+1) 0  
  3.     let rec loop acc = function  
  4.         |[] -> List.rev acc  
  5.         |hd::tl ->   
  6.             if container.[hd] =1 then   
  7.                 loop acc tl  
  8.             else 
  9.                 for j in [hd .. hd .. n] do 
  10.                     container.[j] <- 1  
  11.                 loop (hd::acc) tl      
  12.     loop [] [2 .. n]  
  13.       
  14. let primesBefore120 = GetAllPrimesBefore 120 

廢話少說,直接進入正題吧

  1. let GetAllPrimesBefore n = 

第一行,申明函數(shù)GetAllPrimesBefore, 并且該函數(shù)有一個參數(shù)n, 在這里我沒有指定n的類型,因為編繹器可以通過函數(shù)體對n的類型進去推斷,比如在本例中,n就是int類型,當然我們也可以顯示的指定n的類型,比如 let GetAllPrimesBefore (n:int),這樣我們就指定了n為int型 (注意:(n:int)中的括號不能省略,let GetAllPrimesBefore n : int 的意思是該函數(shù)返回的值的int型)。說完了參數(shù),再說下返回值,同樣,編繹器會根據(jù)函數(shù)體上下文對返回值類型進去推斷,所以我們不需要申明返回類型。

  1. let container = Array.create (n+1) 0 

第二行,首先請注意該行與第一行相對有一個縮進({TAB}),F#和Python一樣,也是通過{TAB}縮進來組織代碼結構的。這一行我們定義了一個變量container,它的類型是Array,大小為 n+1, 并且值全部初使化為0

  1. let rec loop acc = function  
  2.         |[] -> List.rev acc  
  3.         |hd::tl ->   
  4.             if container.[hd] =1 then   
  5.                 loop acc tl  
  6.             else 
  7.                 for j in [hd .. hd .. n] do 
  8.                     container.[j] <- 1  
  9.                 loop (hd::acc) tl  

接下來就是這個函數(shù)的主要部分了(原程序中的3-11行),首先我們定義了一個遞歸函數(shù)(我們發(fā)現(xiàn)定義遞歸函數(shù)需要加rec關鍵字)。它接受兩個參數(shù),acc和一個List,有朋友可能要問了,這里明明我只看到一個參數(shù)acc,你說的那個List在哪呢?可能有細心的朋友也發(fā)現(xiàn)了這里的函數(shù)定義不光前面有rec,在等號后面還加了個function,那么function是做什么用的呢?

  1. let rec loop acc = function 

F#入門:模式匹配

這里我需要首先講一下Pattern Matching(模式匹配), Pattern Matching有些類似于C#中的switch語句(當然它要比C#中的switch強大許多,但這不是本文的目地,所以略去不表),可以根據(jù)expr的值去執(zhí)行某一具體分支,它的基本語法也很簡單,我們還是結合一個具體實例來看一下(例子比較簡單,只是為了說明問題)。 這個例子大家很容易看懂吧,我就不詳細解釋了,只是說明一點,'_'用來匹配所有別的情況。

  1. let ShowGreeting laguageInUse =   
  2.     match laguageInUse with  
  3.     | "C#" -> printfn "Hello, C# developer!" 
  4.     | "F#" -> printfn "Hello, F# developer!" 
  5.     |_ -> printfn "Hello, other developers!" 

因為Pattern Matching在F#中的使用范圍實在太廣了,所以就引入了一種簡化版,這就是上面大家看到的等號后面的function的作用,我們可以把上面的例子簡化成

  1. let ShowGreeting  = function      
  2.     | "C#" -> printfn "Hello, C# developer!" 
  3.     | "F#" -> printfn "Hello, F# developer!" 
  4.     |_ -> printfn "Hello, other developers!" 

怎么樣?既少了給參數(shù)起名的煩惱,也少敲不少字吧,嘿嘿。

F#入門:List基本類型

接下來我再簡單介紹下F#中非常重要的一個基本類型List, 其基本表示形式為 [ item1;item2; .. ;itemn]

F#中List是immutable類型,我們只能訪問里面的值,不能改動里面的值,任何改動List的需求只能通過構建新的List來實現(xiàn)。稍一思考,大家就會很快發(fā)現(xiàn)要實現(xiàn)一個高效的immutable list, 那最簡單的就是對其頭結點進去操作了(插入和刪除都可以達到O(1),當然插入和刪除會構建一個新的List,原List不會改變),F(xiàn)#中的List也是基于這種形式,所有的List都可以看成是Head+Tail(除了Head外的所有結點),F#提供了相應的庫函數(shù)List.hd, List.tl,并且提供了:: (cons operator)來幫助我們方便的構建一個List,比如1::2::[]就表示List [1;2] (注意1和2之間我用的是;不是, 如果寫成[1,2],那個表示該List只有一個元素 (1,2),至于(1,2)是什么類型,為了使文章盡量緊湊,我們今天就不講了)

有了上面這些知識,再看本文一開始的函數(shù)就簡單多了

  1. let rec loop acc = function  
  2.        |[] -> List.rev acc  
  3.        |hd::tl ->   
  4.            if container.[hd] =1 then   
  5.                loop acc tl  
  6.            else 
  7.                for j in [hd .. hd .. n] do 
  8.                    container.[j] <- 1  
  9.                loop (hd::acc) tl   

首先,該函數(shù)的第二個參數(shù)是List,

      當List為空時,就把acc反序返回,

      當List不為空時,把List分成兩部分(hd::tl),檢查當當前值n (n的值等于td) 是否己被標記

            如果己經(jīng)被標記(container.[hd] =1),略過當前值,檢查接下來的值 loop acc tl

            如果沒有被標記(當前值是素數(shù)),用當前值和acc構建一個新List (hd::acc),并對當前值的所有倍數(shù)進去標記(for loop),然后檢查下一個值  loop (hd::acc) tl

這里有兩點需要特別說明一下:

      1. container是一個Array類型的參數(shù),Array在F#中是mutable類型的容器,我們可以修改里面的元素,訪問元素用Array.[i], 修改元素用Array.<-[i] = newValue(不要忘記中間的.)

      2.  for loop的基本形式為 for <index> in <range> do, 我們可以使用[start .. end]或[start .. step .. end]來構建一個range,當然,這里的range其實也是一個List

看完了內部函數(shù),我們再接著往下看(原程序第12行)

  1. loop [] [2 .. n] 

這里就很簡單了,調用我們剛剛定義的內部函數(shù),(acc為空List [], 第二個參數(shù)為List [2 .. n]),其返回值(List acc)就是函數(shù)GetAllPrimesBefore的返回值,F(xiàn)#中函數(shù)有返回值時不需要敲return.

函數(shù)調用也很簡單,(不需要在參數(shù)與函數(shù)名之間加括號)

  1. let primesBefore100 = GetAllPrimesBefore 100 

后記

1. F#中函數(shù)體內可以定義新的值,變量和函數(shù)。(只在當前函數(shù)體內可見)。當然,這樣做的好處顯而易見,我就不啰嗦了。

2. Recursive function是functional programming中很常用的一種算法實現(xiàn)方式。functional programming language往往會針對尾遞歸進行特別的優(yōu)化,F(xiàn)#也不例外,所以我們需要盡可能的把遞歸寫成尾遞歸的形式,這個有時就需要像本文一樣借助accumulator來實現(xiàn)。

本文來自hiber的博客:《結合實例學習F#(一) --快速入門》。

【編輯推薦】

  1. C# Actor的尷尬與F#美麗外表下的遺憾
  2. 函數(shù)式編程語言F#:基于CLR的另一個頭等編程語言
  3. Visual Studio 2010爆F(xiàn)#二進制兼容性問題
  4. 推薦Visual Studio 2010中F#的一些資源
  5. Visual Studio 2010將正式包含F(xiàn)#
責任編輯:yangsai 來源: hiber的博客
相關推薦

2010-01-26 08:25:06

F#語法F#教程

2010-04-07 16:51:59

F#

2010-03-26 19:22:08

F#代理

2010-03-26 19:03:19

F#異步并行模式

2010-03-16 09:09:04

F#

2010-03-26 18:31:59

F#異步并行模式

2010-03-08 09:17:13

F#異步

2009-08-27 09:16:48

F#中DSL原型設計

2010-01-07 10:04:18

F#函數(shù)式編程

2010-01-15 08:33:13

F#F#類型推斷F#教程

2009-08-13 17:39:48

F#數(shù)據(jù)類型Discriminat

2011-06-09 09:52:41

F#

2009-08-19 09:42:34

F#并行排序算法

2009-09-10 14:18:59

Functional F#

2009-11-16 09:05:46

CodeTimer

2012-11-06 10:01:35

ContinuatioF#

2009-12-04 09:16:44

Visual Stud

2009-12-14 09:04:10

F#運算符

2010-04-06 15:20:56

ASP.NET MVC

2009-12-11 13:59:35

F#
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美亚洲国产日韩 | 99亚洲精品视频 | 久久精品欧美电影 | 超碰在线97国产 | 天堂中文av | 成人国产午夜在线观看 | 激情 亚洲 | 亚洲成人一区二区三区 | 国产精品国产馆在线真实露脸 | 久久99精品久久久久久 | 色综合视频在线 | 亚洲欧美在线观看 | 亚洲精品视频在线播放 | 免费亚洲婷婷 | 日韩福利视频 | 日韩一 | 欧美成ee人免费视频 | 国产小u女发育末成年 | 福利在线观看 | 中文字幕高清av | 久草网免费 | 国产精品色 | 国产一区二区三区亚洲 | 欧美精品久久一区 | 国产精品视频网 | 日韩成人在线视频 | 日韩欧美视频在线 | 日韩在线免费电影 | 久久免费精彩视频 | 日韩黄色小视频 | 国产免费观看视频 | 久久久久一区 | 青青草国产在线观看 | 在线一区| 激情影院久久 | 久久国产精品72免费观看 | 亚洲欧美综合精品久久成人 | 欧美激情精品久久久久 | 日韩成人高清在线 | 中文字幕日韩欧美一区二区三区 | 欧美xxxx做受欧美 |