424dc3517e5dba9050d6b2b2e7d804b434e02016
[fsharp-ref.git] / FSharpRef / Functional.fs
1 module Functional
2
3 open System.IO
4 open System.Linq
5
6 // For dynmic typing. To print anything in our case.
7 let inline print a = printfn "%A" a
8
9 // Write something on a file.
10 let appendFile (filename: string) (text: string) =
11 use sw = new StreamWriter(filename, true)
12 sw.WriteLine(text)
13
14 // Recursive function.
15 let rec fac n =
16 if n <= 1 then 1
17 else n * fac (n - 1)
18
19 // Mutual recursive functions.
20 let rec isEven n =
21 if n = 0 then true
22 elif n = 1 then false
23 else isOdd (n - 1)
24 and isOdd n =
25 if n = 0 then false
26 elif n = 1 then true
27 else isEven (n - 1)
28
29 // Algebraic data type.
30 type Suit =
31 | Diamond
32 | Spade
33 | Heart
34 | Club
35
36 type PlayingCard =
37 | Ace of Suit
38 | King of Suit
39 | Queen of Suit
40 | Jack of Suit
41 | NumCard of int * Suit
42 member this.Value = // Property.
43 match this with
44 | Ace (_) -> 14
45 | King (_) -> 13
46 | Queen (_) -> 12
47 | Jack (_) -> 11
48 | NumCard (n, _) when n >= 2 && n <= 10 -> n
49 | NumCard (_) -> failwith "Card has invalid value!"
50
51 let deckOfCards =
52 [
53 for suit in [ Spade; Club; Heart; Diamond ] do
54 yield Ace(suit)
55 yield King(suit)
56 yield Queen(suit)
57 yield Jack(suit)
58 for n in [2 .. 10] do
59 yield NumCard(n, suit)
60 ]
61
62 // Records.
63 type Person = { First: string; Last: string; Age: int }
64 let steve = { First = "Steve"; Last = "Holt"; Age = 17 }
65 let steves'twin = { steve with First = "Paul" }
66
67 // Queries. Should be used with SQL or other external data sources.
68 let youngPersonNames persons =
69 query {
70 for p in persons do
71 where (p.Age < 15)
72 select p.First
73 }
74
75 // Infinite lazy sequence.
76 let allPositiveInts =
77 seq {
78 for i in 1 .. System.Int32.MaxValue do
79 yield i
80 }
81 let rec fibs x y =
82 seq {
83 yield x
84 yield! fibs y (x + y)
85 }
86 let testYieldBang =
87 seq {
88 yield 10
89 yield! [1; 2; 3] // Yields a collection.
90 }
91 // Generator.
92 let testUnfold =
93 Seq.unfold (fun a -> if a > 10 then None else Some(10 * a, a + 1)) 1
94
95 // Functions composition.
96 let SizeOfFolder =
97 let getFiles folder =
98 Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories)
99 getFiles
100 >> Array.map (fun file -> (new FileInfo(file)).Length)
101 >> Array.sum
102
103 // Matches literals.
104 [<Literal>]
105 let Bill = "Bill Gates" // Must begin with a capital!
106 let greet name =
107 match name with
108 | Bill -> "Hello rich Bill!"
109 | name -> sprintf "Hello poor %s" name
110
111 // Matches tuples.
112 let testXor x y =
113 match x, y with
114 | a, b when a <> b -> true
115 | _ -> false