递归
运算符
Function Application
模式匹配
控制流
递归
F#中使用递归函数,需要用到rec关键字,表示(Recursion)。看个例子就明白了,计算斐波那契数。
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
)
运算符
和C#一样,F#的运算符也能支持很多类型的操作。但是有一点要注意,C#中运算符两边的操作数类型可以不一致,但是F#中操作数类型必须一致,否则编译器报错。
F#中,也可以重新定义操作符,将操作符加上括号,该操作符就变成一个值了。比如下面的代码:
let result = (+) 1 1
此处 (+)就是一个方法的名字,后面跟着2个参数。
也可以自定义运算符,比如:
let
(
+
)
a b
=
a
-
b
printfn
"%i"
(
1
+
1
)
算出的结果是0
let
(
+*
)
a b
=
(a
+
b
)
*
a
*
b
printfn
"(1 +* 2) = %i"
(
1
+*
2
)
结果是6
Function Application
Function Application也称做function composition 或者composing functions(复合函数)。个人认为是一个语法糖。
采用符号|>来复合函数。定义如下,let (|>) x f = f x
举个例子
let result = System.Math.Cos 0.5
转换一下就是
let result = 0.5 |> System.Math.Cos
在某些情况下,这个功能很有用,比如下面的代码:
let add x y = x + y
let result = add 6 7 |> add 4 |> add 5
模式匹配
就是类似C#中的switch语句,但是在F#中,比C#更加灵活强大。
看几个例子就明白了。
// definition of Lucas numbers using pattern matching
let
rec
luc x
=
match
x
with
| x
when
x
<=
0
->
failwith
"value must be greater than 0"
|
1
->
1
|
2
->
3
| x
->
luc
(
x
-
1
)
+
luc
(
x
-
2
)
// call the function and print the results
printfn
"(luc 2) = %i"
(
luc
2
)
printfn
"(luc 6) = %i"
(
luc
6
)
printfn
"(luc 11) = %i"
(
luc
11
)
printfn
"(luc 12) = %i"
(
luc
12
)
可以忽略第一个|,如果要匹配的逻辑很短小的话,并且可以写在一行上。而且,可以使用"_"作为通配符。
let
booleanToString x
=
match
x
with
false
->
"False"
| _
->
"True"
printfn
"%s"
(booleanToString
true
)
也可以把2个匹配条件写在一起。
let
stringToBoolean x
=
match
x
with
|
"True"
|
"true"
->
true
|
"False"
|
"false"
->
false
| _
->
failwith
"unexpected input"
printfn
"(stringToBoolean \"True\") = %b"
(stringToBoolean
"True"
)
也可以同时匹配多个参数。
let
myOr b1 b2
=
match
b1, b2
with
|
true, _
->
true
| _,
true
->
true
| _
->
false
let
myAnd p
=
match
p
with
|
true,
true
->
true
| _
->
false
printfn
"(myOr true false) = %b"
(myOr
true
false
)
printfn
"(myOr false false) = %b"
(myOr
false
false
)
printfn
"(myAnd (true, false)) = %b"
(myAnd
(
true,
false
)
)
printfn
"(myAnd (true, true)) = %b"
(myAnd
(
true,
true
)
)
由于匹配语句很常用,因此F#提供了
快捷模式。如果一个函数主要使用匹配值功能,那么就可以使用这个快捷语法。使用关键字function,把模式放在函数参数的地方,用“|”分割匹配规则。如下代码:
// concatenate a list of strings into single string
let
rec
conactStringList
=
function
head :: tail
->
head
+
conactStringList tail |
[
]
->
""
// test data
let
jabber
=
[
"'Twas "
;
"brillig, "
;
"and "
;
"the "
;
"slithy "
;
"toves "
;
"..."
]
// call the function
let
completJabber
=
conactStringList jabber
// print the result
printfn
"%s"
completJabber
控制流
F#中,if语句的返回值必须是同一种类型
let
result
=
if
System.
DateTime.
Now.
Second
%
2
=
0
then
"heads"
else
"tails"
printfn
"%A"
result
let
result1
=
if
System.
DateTime.
Now.
Second
%
2
=
0
then
box
"heads"
//必须是同一种类型,装箱操作;
else
box
false
printfn
"%A"
result1