module Functional open System.IO open System.Linq // Write something on a file. let appendFile (filename: string) (text: string) = use sw = new StreamWriter(filename, true) sw.WriteLine(text) // Recursive function. let rec fac n = if n <= 1 then 1 else n * fac (n - 1) // Mutual recursive functions. let rec isEven n = if n = 0 then true elif n = 1 then false else isOdd (n - 1) and isOdd n = if n = 0 then false elif n = 1 then true else isEven (n - 1) // Algebraic data type. type Suit = | Diamond | Spade | Heart | Club type PlayingCard = | Ace of Suit | King of Suit | Queen of Suit | Jack of Suit | NumCard of int * Suit member this.Value = // Property. match this with | Ace (_) -> 14 | King (_) -> 13 | Queen (_) -> 12 | Jack (_) -> 11 | NumCard (n, _) when n >= 2 && n <= 10 -> n | NumCard (_) -> failwith "Card has invalid value!" let deckOfCards = [ for suit in [ Spade; Club; Heart; Diamond ] do yield Ace(suit) yield King(suit) yield Queen(suit) yield Jack(suit) for n in [2 .. 10] do yield NumCard(n, suit) ] // Records with custom equality. [] type Person = { First: string; Last: string; Age: int } override this.Equals(other) = match other with | :? Person as p -> p.First = this.First && p.Last = this.Last | _ -> false override this.GetHashCode() = this.First.GetHashCode() ^^^ this.Last.GetHashCode() let steve = { First = "Steve"; Last = "Holt"; Age = 17 } let stevesTwin = { steve with First = "Paul" } // Queries. Should be used with SQL or other external data sources. let youngPersonNames persons = query { for p in persons do where (p.Age < 15) select p.First } // Infinite lazy sequence. let allPositiveInts = seq { for i in 1 .. System.Int32.MaxValue do yield i } let rec fibs x y = seq { yield x yield! fibs y (x + y) } let testYieldBang = seq { yield 10 yield! [1; 2; 3] // Yields a collection. } // Generator. let testUnfold = Seq.unfold (fun a -> if a > 10 then None else Some(10 * a, a + 1)) 1 // Functions composition. let SizeOfFolder = let getFiles folder = Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories) getFiles >> Array.map (fun file -> (new FileInfo(file)).Length) >> Array.sum // Matches literals. [] let Bill = "Bill Gates" // Must begin with a capital! let greet name = match name with | Bill -> "Hello rich Bill!" | name -> sprintf "Hello poor %s" name // Matches tuples. let testXor x y = match x, y with | a, b when a <> b -> true | _ -> false