F#...函數式程式設計語言,每個運算式都是一個函數式的。function is values。
printf 方法 with %A pattern to output them to the console.
%A可以顯示任何類型,類似於c#中的ToString 。
也可以使用print_any and any_to_string方法。
printf_string :列印一個string類型
printf_int:列印一個int類型。
...
1.values and Function:
sample:
#light
let n = 10
let add a b = a + b
let addFour = add 4
let result = addFour n
printfn "result = %i" result
------------
result=14
不必一次傳入所有的參數,因為一個方法就是一個值,所以,在addFour中只傳入一個參數,當add方法沒有收到所有的參數,它會產生一個新的方法,並wait,直到另一個參數傳來然後返回一個value。
如果一個方法必須輸入兩個參數,可以使用let add (a,b) = a+b的方式,這樣add方法必須要輸入兩個參數了。
2.在f#中方法體都是使用縮排來判斷的。如下:
#light
let halfWay a b =
let dif = b - a
let mid = dif / 2
mid + a
printfn "(halfWay 5 11) = %i" (halfWay 5 11)
printfn "(halfWay 11 5) = %i" (halfWay 11 5)
--------
(halfWay 5 11) = 8
(halfWay 11 5) = 8
#light: 必須放在f#檔案的最開頭,這個表示可以使f#識別空格等,否則必須要輸入begin,in等等的一些關鍵字了。
halfWay 方法,有兩個參數,a,b,並返回一個value.
3.變數範圍。
在f#中,變數的範圍,方法中,方法中的定義的變數在方法結束後,失去作用。
#light
let defineMessage() =
let message = "Help me"
print_endline message
print_endline message
--error.
#light
let mathsPuzzle() =
print_string "Enter day of the month on which you were born: "
let input = read_int ()
let x = input * 4 // Multiply it by 4
let x = x + 13 // Add 13
let x = x * 25 // Multiply the result by 25
let x = x - 200 // Subtract 200
print_string "Enter number of the month you were born: "
let input = read_int ()
let x = x + input
let x = x * 2 // Multiply by 2
let x = x - 40 // Subtract 40
let x = x * 50 // Multiply the result by 50
print_string "Enter last two digits of the year of your birth: "
let input = read_int ()
let x = x + input
let x = x - 10500 // Finally, subtract 10,500
printf "Date of birth (ddmmyy): %i" x
mathsPuzzle()
在方法中,可以重複定義一個變數並使用,而不用使用一個中間變數。
4.遞迴
遞迴就是自己調用自己咯..在f#中,使用在let之後使用關鍵字rec,表示方法可以被自己調用。
#light
let rec fib x =
match x with
| 1 -> 1
| 2 -> 1
| x -> fib (x - 1) + fib (x - 2)
printfn "(fib 2) = %i" (fib 2)
printfn "(fib 6) = %i" (fib 6)
printfn "(fib 11) = %i" (fib 11)
當然使用遞迴方法的時候要小心,否則進入死迴圈中了哦。這樣會消耗掉你系統資源,知道throw System.StackOverflowException.
5.匿名Function
在f#中提供另外一種方式定義方法,使用fun 關鍵字和function關鍵字。
#light
let x = (fun x y -> x + y) 1 2
let x1 = (function x -> function y -> x + y) 1 2
let x2 = (function (x, y) -> x + y) (1, 2)
6.Operators
F# has two different kinds of operators, prefix and infix; a prefix operator is an operator
that takes one operand, and an infix operator takes two or more. Prefix operators appear
before their operand, whereas infix operators appear between the first two operands
F#可以重新定義操作符。例如
#light
let (+) a b = a - b
print_int (1 + 1)
User-defined (custom) operators must be nonalphanumeric and can be a single character
or a group of characters. You can use the following characters in custom operators:
!$%&*+-./<=>?@^|~
:
自訂動作符,可以是上面第一行中任何一個字元開始。例如:
#light
let ( +:* ) a b = (a + b) * a * b
printfn "(1 +:* 2) = %i" (1 +:* 2)
---
(1 +:* 2) = 6
7.List
在F#中可以使用::,將一個值插入到list的前面,如:
#light
let emptyList = []
let oneItem = "one " :: []
let twoItem = "one " :: "two " :: []
list的定義是一個大括弧和使用';'分隔
#light
let shortHand = ["apples "; "pairs "]
list中可以使用@ 將兩個list串連起來。
let twoLists = ["one, "; "two, "] @ ["buckle "; "my "; "shoe "]
list中的元素必須是相同類型的,如果要往twoLists中插入一個int的類型,編譯的時候會有Error。
如果要在list中放入不同類型的元素,可以使用obj,如下:
let objList = [box 1; box 2.0; box "three"]
sample:
#light
#nowarn"62"
open System
let emptyList = []
let oneItem = "one " :: []
let twoItem = "one " :: "two " :: []
let shortHand = ["apples "; "pairs "]
let twoLists = ["one, "; "two, "] @ ["buckle "; "my "; "shoe "]
let objList = [box 1; box 2.0; box "three"]
let printList l =
List.iter print_string l
print_newline()
let main() =
printList emptyList
printList oneItem
printList twoItem
printList shortHand
printList twoLists
for x in objList do
print_any x
print_char ' '
print_newline()
main()
Console.ReadKey()
----
one
one two
apples pairs
one, two, buckle my shoe
1 2.000000 "three"
List建立後是不可改變的,但是可以給一個新的list複製,也可以使用List.rev 將list中的元素顛倒併產生一個新的list。如下:
#light
let one = ["one "]
let two = "two " :: one
let three = "three " :: two
let rightWayRound = List.rev three
let printList l =
List.iter print_string l
print_newline()
let main() =
printList one
printList two
printList three
printList rightWayRound
main()
-----
one
two one
three two one
one two three
--
List.hd:取出List中的第一個元素。
List.tl :取出剩下的元素。
#light
#nowarn"62"
open System
let listOfList = [[2; 3; 5]; [7; 11; 13]; [17; 19; 23; 29]]
let rec concatList l =
if List.nonempty l then
let head = List.hd l
let tail = List.tl l
head @ (concatList tail)
else
[]
let primes = concatList listOfList
print_any primes
Console.ReadKey()
List.iter : List的方法,有兩個參數,第一個是一個方法,用於定義要應用每個list元素的方法,第二個參數要應用的list。其實就是一個for loop的簡單寫法。
8.List Comprehensions
.. :從第一個數字,+1,知道=最後一個數字。
#light
let numericList = [ 0 .. 9 ]
let alpherSeq = { 'A' .. 'Z' }
printfn "%A" numericList
printfn "%A" alpherSeq
The results of this example are as follows:
[0; 1; 2; 3; 4; 5; 6; 7; 8; 9]
seq ['A'; 'B'; 'C'; 'D'; ...]
list 還可以定義步長的方式定義一個list,使用兩個.
如:
#light
let multiplesOfThree = [ 0 .. 3 .. 30 ]
let revNumericSeq = [ 9 .. -1 .. 0 ]
printfn "%A" multiplesOfThree
printfn "%A" revNumericSeq
[0; 3; 6; 9; 12; 15; 18; 21; 24; 27; 30]
[9; 8; 7; 6; 5; 4; 3; 2; 1; 0]
也可以定義一個迴圈來定義一個list,如:
#light
let squares =
{ for x in 1 .. 10 -> x * x }
print_any squares
9.流程式控制制
if ...then ....else....
#light
let result =
if System.DateTime.Now.Second % 2 = 0 then
"heads"
else
"tails"
print_string result
if 語句返回必須是相同的類型,如果要返回不同的類型,可以使用ojbect封裝一下。
#light
let result =
if System.DateTime.Now.Second % 2 = 0 then
box "heads"
else
box false
print_any result