F# Fundamentals
F# Fundamentals 基本语法
先是一些简单示例
1.Hello World
Printfn "Hello World"
2.简单的Windows Form程序
open System.Windows.Form
let form = new Form (Visible=true)
form.Click.Add (fun _ -> printfn "click")
Application.Run form
let form = new Form (Visible=true)
form.Click.Add (fun _ -> printfn "click")
Application.Run form
3.斐波那契数列
let rec fib x =
if x < 2 then 1
else fib (x–1) + fib (x-2)
let results = Array.map fib [| 1 .. 40 |]
printfn "results = %A" results
if x < 2 then 1
else fib (x–1) + fib (x-2)
let results = Array.map fib [| 1 .. 40 |]
printfn "results = %A" results
感觉怎么样,嘿嘿,OCAML的语法,刚开始看起来肯定是挺晕的。
let关键字
let关键字用来绑定(binding)
let data = (1, 2, 3) //绑定一个静态值
let f (a, b, c) = //绑定一个静态方法
let sum = a + b + c //绑定一个局部变量
let g x = sum + x*x //绑定一个局部方法
(g a, g b, g c)
let f (a, b, c) = //绑定一个静态方法
let sum = a + b + c //绑定一个局部变量
let g x = sum + x*x //绑定一个局部方法
(g a, g b, g c)
不解释,很简单,类似于JavaScript中的var。
F#中的注释
// comment
(* comment *) --- 这种注释方式在别的语言中还真没见过,孤陋寡闻了。。。
(* comment *) --- 这种注释方式在别的语言中还真没见过,孤陋寡闻了。。。
F#中的函数
(fun x -> x + 1) ---匿名函数
let f x = x + 1
(f, f)
val f : int -> int
let f x = x + 1
(f, f)
val f : int -> int
F#中的操作符
由于F#允许操作符重载,而且支持的操作符也较多,所以显得有些混乱,如果想了解具体的重载规则,请参考老赵的这篇文章http://www.cnblogs.com/JeffreyZhao/archive/2009/12/14/fsharp-operator.html
算术运算符
Overloaded Arithmetic
x + y Addition
x - y Subtraction
x * y Multiplication
x / y Division
x % y Remainder/modulus
-x Unary negation
x + y Addition
x - y Subtraction
x * y Multiplication
x / y Division
x % y Remainder/modulus
-x Unary negation
逻辑运算符
not expr Boolean negation
expr && expr Boolean “and”
expr || expr Boolean “or”
expr && expr Boolean “and”
expr || expr Boolean “or”
F#的基础类型
F#的类型推断系统是很牛X的,具体怎么牛,大家自己慢慢研究吧。。。
下面是F#的基本类型
Basic Types/Literals
int 76
string "abc", @"c:\etc"
float 3.14, 3.2e5
char '7'
bool true, false
unit ()
int 76
string "abc", @"c:\etc"
float 3.14, 3.2e5
char '7'
bool true, false
unit ()
因为也是基于CLR的,所以基本类型都差不多。
但是F#为了科学计算,所以又增加了一些类型支持。
Basic Types and Literals
sbyte = System.SByte 76y
byte = System.Byte 76uy
int16 = System.Int16 76s
uint16 = System.UInt16 76us
int32 = System.Int32 76
uint32 = System.UInt32 76u
int64 = System.Int64 76L
uint64 = System.UInt64 76UL
string = System.String "abc", @"c:\etc"
single = System.Single 3.14f
double = System.Double 3.14, 3.2e5
char = System.Char '7'
nativeint = System.IntPtr 76n
unativeint = System.UIntPtr 76un
bool = System.Boolean true, false
unit = FSharp.Core.Unit ()
obj = System.Object box 5
exn = System.Exception new ArgumentException()
bigint = FSharp.Math.BigInt 1024I * 1024I * 1024I * 1024I
sbyte = System.SByte 76y
byte = System.Byte 76uy
int16 = System.Int16 76s
uint16 = System.UInt16 76us
int32 = System.Int32 76
uint32 = System.UInt32 76u
int64 = System.Int64 76L
uint64 = System.UInt64 76UL
string = System.String "abc", @"c:\etc"
single = System.Single 3.14f
double = System.Double 3.14, 3.2e5
char = System.Char '7'
nativeint = System.IntPtr 76n
unativeint = System.UIntPtr 76un
bool = System.Boolean true, false
unit = FSharp.Core.Unit ()
obj = System.Object box 5
exn = System.Exception new ArgumentException()
bigint = FSharp.Math.BigInt 1024I * 1024I * 1024I * 1024I
F#的管道符
这东西早就有一大堆东西支持了,比如powershell,linux shell等
无非就是前个函数的输出作为下一个函数的输入罢了
x |> f
x |> f1
|> f2
|> f3
|> f2
|> f3
看一个具体的应用
open System.IO
let files =
Directory.GetFiles(@"c:\", "*.*",
SearchOption.AllDirectories)
let totalSize =
files
|> Array.map (fun file -> FileInfo file)
|> Array.map (fun info -> info.Length)
|> Array.sum
let files =
Directory.GetFiles(@"c:\", "*.*",
SearchOption.AllDirectories)
let totalSize =
files
|> Array.map (fun file -> FileInfo file)
|> Array.map (fun info -> info.Length)
|> Array.sum