一段 code 幾乎包含 F# 所有語法

F# 的語法雖然很精簡,但還是得稍微花時間學習,Scott Wlaschin 所寫的這份 code,幾乎包含 F# 的所有語法,若都看得懂,F# 語法部分就算過關了。

Version


F# 4.1

Overview of F# Syntax


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// This is presented with permission from Scott Wlaschin, the original author.  This has been slightly modified.
// Single line comments use a double slash.
(*
Multi-line comments can be done this way (though double-slash is usually used).
*)


// ======== "Variables" (but not really) ==========
// The "let" keyword defines an (immutable) value
let myInt = 5
let myFloat = 3.14
let myString = "hello" // note that no types needed

// ======== Lists ============
let twoToFive = [ 2; 3; 4; 5 ] // Square brackets create a list with
// semicolon delimiters.
let oneToFive = 1 :: twoToFive // :: creates list with new 1st element
// The result is [1; 2; 3; 4; 5]

let zeroToFive = [0;1] @ twoToFive // @ concats two lists

// IMPORTANT: commas are never used as delimiters, only semicolons!

// ======== Functions ========
// The "let" keyword also defines a named function.
let square x = x * x // Note that no parens are used.
square 3 // Now run the function. Again, no parens.

let add x y = x + y // don't use add (x,y)! It means something
// completely different.
add 2 3 // Now run the function.

// to define a multiline function, just use indents. No semicolons needed.
let evens list =
let isEven x = x % 2 = 0 // Define "isEven" as an inner ("nested") function
List.filter isEven list // List.filter is a library function
// with two parameters: a boolean function
// and a list to work on

evens oneToFive // Now run the function

// You can use parens to clarify precedence. In this example,
// do "map" first, with two args, then do "sum" on the result.
// Without the parens, "List.map" would be passed as an arg to List.sum
let sumOfSquaresTo100 =
List.sum (List.map square [ 1 .. 100 ])

// You can pipe the output of one operation to the next using "|>"
// Here is the same sumOfSquares function written using pipes
let sumOfSquaresTo100piped =
[ 1 .. 100 ] |> List.map square |> List.sum // "square" was defined earlier

// you can define lambdas (anonymous functions) using the "fun" keyword
let sumOfSquaresTo100withFun =
[ 1 .. 100 ] |> List.map (fun x -> x * x) |> List.sum

// In F# returns are implicit -- no "return" needed. A function always
// returns the value of the last expression used.

// ======== Pattern Matching ========
// Match..with.. is a supercharged case/switch statement.
let x = "a"
match x with
| "a" -> printfn "x is a"
| "b" -> printfn "x is b"
| _ -> printfn "x is something else" // underscore matches anything

// Some(..) and None are roughly analogous to Nullable wrappers
let validValue = Some(99)
let invalidValue = None

// In this example, match..with matches the "Some" and the "None",
// and also unpacks the value in the "Some" at the same time.
let optionPatternMatch input =
match input with
| Some i -> printfn "input is an int=%d" i
| None -> printfn "input is missing"

optionPatternMatch validValue
optionPatternMatch invalidValue

// ========= Complex Data Types =========

// Tuple types are pairs, triples, etc. Tuples use commas.
let twoTuple = (1, 2)
let threeTuple = ("a", 2, true)

// Record types have named fields. Semicolons are separators.
type Person = { First: string; Last: string }

let person1 = { First="John"; Last="Doe" }
// You can also use new lines to elide the semiclon.
let person2 =
{ First="Jane"
Last="Doe" }

// Union types have choices. Vertical bars are separators.
type Temp =
| DegreesC of float
| DegreesF of float

let temp = DegreesF 98.6

// Types can be combined recursively in complex ways.
// E.g. here is a union type that contains a list of the same type:
type Employee =
| Worker of Person
| Manager of Employee list

let jdoe = { First="John"; Last="Doe" }
let worker = Worker jdoe

// ========= Printing =========
// The printf/printfn functions are similar to the
// Console.Write/WriteLine functions in C#.
printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true
printfn "A string %s, and something generic %A" "hello" [ 1; 2; 3; 4 ]

// all complex types have pretty printing built in
printfn "twoTuple=%A,\nPerson=%A,\nTemp=%A,\nEmployee=%A"
twoTuple person1 temp worker

Reference


.NET Blog, Get Started with F# as a C# developer

2018-03-16