F#初学笔记03

Lists
F#中List类型类似集合类型。list可以是空的list,用方括号[]表示。F#中可以连结值,使用量过冒号::把值串联一个list中。
let emptyList = []
let oneItem = "one " :: []
let twoItem = "one " :: "two " :: []
最后一个必须要是list,不管是不是空的。
上述采用连结的方式定义比较冗长,可以使用快捷方式定义list,只需要在[]中用分号分割元素就行了。 
let  shortHand  =   [ "apples " ;   "pears" ]
使用@操作符可以把2个list合并为1个。
let twoLists = ["one, "; "two, "] @ ["buckle "; "my "; "shoe "]
list中元素的类型必须是一致的。

 
使用List
F#中list通常用于模式匹配或者递归。从list中取出第一个元素的语法和连结一个元素到list中是一样的。 由一个标识符表示head,后面2个冒号,接下来一个标识符表示剩下的list。如下面的例子:
// list to be concatenated
let  listOfList   =   [ [ 2 ;   3 ;   5 ] ;   [ 7 ;   11 ;   13 ] ;   [ 17 ;   19 ;   23 ;   29 ] ]
// definition of a concatenation function
let   rec  concatList l   =
     match  l   with
    | head :: tail   ->  head @   (concatList tail )
    |   [ ]   ->   [ ]
// call the function
let  primes   =  concatList listOfList
// print the results
printfn   "%A"  primes

 
遍历List
//遍历list
let   rec  visit l   =
     match  l   with
    | head :: tail   ->  
        printfn   "%i"  head
        visit tail
    |   [ ]   ->   ( )
// some test data
let  testSequence   =   [ 1 ;   2 ;   3 ;   4 ;   5 ;   6 ;   7 ; ]
// call the function
visit testSequence
结果如下:
d93156ce54c849e0b19a36a21f433e88

 
取出list的头,递归的处理剩下的list,这在模式匹配中是常用的方法。但不是仅有的方法。下面也是几种常用的方法。
// function that attempts to find various sequences
let   rec  findSequence l   =
     match  l   with
     // match a list containing exactly 3 numbers
    |   [x ;  y ;  z ]   ->
        printfn   "Last 3 numbers in the list were %i %i %i"  x y z
     // match a list of 1, 2, 3 in a row
    |   1  ::   2  ::   3  :: tail   ->
        printfn   "Found sequence 1, 2, 3 within the list"
        findSequence tail
     // if neither case matches and items remain
     // recursively call the function
    | head :: tail   ->  findSequence tail
     // if no items remain terminate
    |   [ ]   ->   ( )
// some test data
let  testSequence   =   [ 1 ;   2 ;   3 ;   4 ;   5 ;   6 ;   7 ;   8 ;   9 ;   8 ;   7 ;   6 ;   5 ;   4 ;   3 ;   2 ;   1 ]
// call the function
findSequence testSequence

 
上例中,第一个匹配规则匹配固定长度的list,只含有3个元素的list。
第二个匹配规则,是检测是否有序列1,2,3在list中。
最后2个规则是标准的head/tail处理。
结果如下:
ce33b3cf9d194f2c96122c6ea0642205

 

 
对list中每个元素做操作,F#核心库包含有一个函数 map,定义在List模块中,它的定义如下:
let   rec  map func list   =
     match  list   with
    | head :: rest   ->
        func head :: map func rest
    |   [ ]   ->   [ ]

 
所以,可以有如下的写法:
let  addfunc i =
  i + 1
let  alist = [ 1 ;   2 ;   3 ]
let  blist =map addfunc alist

printfn   "%A"  blist
结果如下:
0ff78068b9124e70a29bb5f14efc4205

 
List Comprehensions
这个术语不知道怎么翻译贴切,没找到合适的中文翻译。
维基百科的描述:
A list comprehension is a syntactic construct available in some programming languages for creating a list based on existing lists.
大意就是list comprehension一个语法的结构,它能基于一个已经存在的list创建一个list。
看到一句话,可能更加贴切:
"A List Comprehension is a way to apply some function to every member of a list."

 
F#中的sequence,list和array可以直接使用comprehension语法。Sequences是类型序列的集合,也就是.NET BCL(基础类库)中的IEnumerable类型在F#中的名称。

 
最简单的comprehension应用是指定范围。如下例子:
let  numericList   =   [   0  ..   9   ]
let  alpherSeq   =   seq   {   'A'  ..   'Z'   }
let  multiplesOfThree   =   [   0  ..   3  ..   30   ]
let  revNumericSeq   =   [   9  ..   - 1  ..   0   ]

printfn   "%A"  numericList
printfn   "%A"  alpherSeq
printfn   "%A"  multiplesOfThree
printfn   "%A"  revNumericSeq

 
List comprehensions允许从一个集合上,循环创建集合。只需要用for。如下代码
// a sequence of squares
let  squares   =
     seq   {   for  x   in   1  ..   10   ->  x   *  x   }
// print the sequence
printfn   "%A"  squares

let  list   =
     [   for  x   in   1  ..   10   ->  x   *  x   ]
// print the list
printfn   "%A"  list
注意使用seq和list打印的结果有些差别。
343a9eeb47ab4f448cbe94724ad025ca

 
F#使用yield关键字,可以更加灵活的控制哪个元素可以生成,那个不需要生成。如下代码:
// a sequence of even numbers
let  evens n   =
     seq   {   for  x   in   1  ..   n   do
             if  x   %   2   =   0   then   yield  x   }
     // print the sequence
printfn   "%A"   (evens   10 )

let  squarePoints n   =
     seq   {   for  x   in   1  ..   n   do
             for  y   in   1  ..   n   do
                 yield  x, y   }
// print the sequence
printfn   "%A"   (squarePoints   3 )

 

 

你可能感兴趣的:(F#)