Created
April 1, 2014 00:23
-
-
Save MartinBodocky/9905278 to your computer and use it in GitHub Desktop.
Chapter 2-3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let snacks = ("Soda", "Cookies", "Candy") | |
let x, y, z = snacks | |
let tens = [0 .. 10 ..50] | |
let countDown = [5L .. -1L .. -5L] | |
let x2 = | |
[ let negate x = -x | |
for i in 1 .. 10 do | |
if i % 2 = 0 then | |
yield negate i | |
else | |
yield i | |
] | |
let primeUnder max = | |
[ | |
for n in 1 .. max do | |
let factorsOfN = | |
[ | |
for i in 1 .. n do | |
if n % i = 0 then | |
yield i | |
] | |
//n is prime if its only factor are 1 and n | |
if List.length factorsOfN = 2 then | |
yield n | |
] | |
primeUnder 50 | |
let isMultipleOf5 x = (x % 5 = 0) | |
let multOf5, nonMultOf5 = List.partition isMultipleOf5 [1..15] | |
let square x = x * x | |
List.map square [1..12] | |
let insertCommas (acc : string) item = acc + ", " + item | |
List.reduce insertCommas ["Jack"; "Jill"; "Stefan"; "Maria"] | |
let addAccToListItem acc i = acc + i | |
List.fold addAccToListItem 0 [1;2;3] | |
let countVowels (str : string) = | |
let charList = List.ofSeq str | |
let accFunc (As, Es, Is, Os, Us) letter = | |
if letter = 'a' then (As + 1, Es,Is, Os, Us) | |
elif letter = 'e' then (As, Es+1, Is, Os, Us) | |
elif letter = 'i' then (As, Es, Is + 1, Os, Us) | |
elif letter = 'o' then (As, Es, Is, Os+1, Us) | |
elif letter = 'u' then (As, Es, Is, Os, Us + 1) | |
else (As, Es, Is, Os, Us) | |
List.fold accFunc (0,0,0,0,0) charList | |
countVowels "The quick brown fox jumps over the lazy dog" | |
let printNumbers x = printfn "Printing %d" x | |
List.iter printNumbers [1..3] | |
open System | |
let isInteger str = | |
let successful, result = Int32.TryParse(str) | |
if successful | |
then Some(result) | |
else None | |
let wrong = isInteger "Lol" | |
isInteger "12" | |
//Option.get wrong | |
//using Option.get | |
let isLessThanZero x = (x < 0) | |
let containsNegativeNumbers intList = | |
let filteredList = List.filter isLessThanZero intList | |
if List.length filteredList > 0 | |
then Some(filteredList) | |
else None | |
let negativeNumbers = containsNegativeNumbers [6; 20; -8;45; -5] | |
Option.get negativeNumbers | |
let mountain = "K2" | |
let height = 8611 | |
let units = 'm' | |
printfn "%s is %d%c high" mountain height units | |
//type inference from printf :) | |
let inferParams x y z = | |
printfn "x = %f, y = %s, z = %b" x y z | |
inferParams 12.0 "a" false | |
// based on ToString on object | |
printfn "%O" [] | |
// based on the same as above plus attribute StructureFormatDisplay | |
printfn "%A" [] | |
//result of printing as string | |
let location = "Oxford" | |
sprintf "I'm typing in %s" location | |
// Append text to a file | |
open System.IO | |
let appendFile (fileName : string) (text: string) = | |
use file = new StreamWriter(fileName, true) | |
file.WriteLine(text) | |
file.Close() | |
appendFile @"C:\file.txt" "Processing A" | |
let appendToLog = appendFile @"C:\log.txt" | |
appendToLog "Processing B" | |
//Functions return functions | |
let generatePowerOfFunc baseValue = | |
(fun exponent -> baseValue ** exponent) | |
let powerOfTwo = generatePowerOfFunc 2.0 | |
let powerOfThree = generatePowerOfFunc 3.0 | |
powerOfTwo 8.0 | |
powerOfThree 3.0 | |
open System | |
//functional for loop | |
let rec forLoop body times = | |
if times <= 0 then | |
() | |
else | |
body() | |
forLoop body (times - 1) | |
//functional while loop | |
let rec whileLoop predicate body = | |
if predicate() then | |
body() | |
else | |
() | |
forLoop (fun () -> printfn "Looping ... ") 5 | |
whileLoop | |
(fun () -> 3 = (new Random()).Next(0,8)) | |
(fun () -> printfn "Great") | |
//Mutually recursive functions using rec and and | |
let rec isOdd x = | |
if x = 0 then false | |
elif x = 1 then true | |
else isEven (x - 1) | |
and isEven x = | |
if x = 0 then true | |
elif x = 1 then false | |
else isOdd (x - 1) | |
isEven 314 | |
isOdd 314 | |
//factorial | |
let rec (!) x = | |
if x<=1 then 1 | |
else x * !(x-1) | |
!5 | |
// define === to compare strings based on reguler expressions | |
open System.Text.RegularExpressions | |
let (===) str (regex : string) = | |
Regex.Match(str, regex).Success | |
"The quick brown fox " === "The (.*) fox" | |
//Sum a list using (+) symbolic function | |
List.fold (+) 0 [1..10] | |
//Multiply all elements using the (*) symbolic function | |
List.fold (*) 1 [1 .. 10] | |
let minus = (-) | |
List.fold minus 10 [1..3] | |
//operators | |
//wrong example | |
open System | |
open System.IO | |
let sizeOfFolder folder = | |
//Get all files under the path | |
let filesInFolder : string [] = | |
Directory.GetFiles( | |
folder, "*.*", | |
SearchOption.AllDirectories) | |
//Map those files to their corresponding FileInfos | |
let fileInfos : FileInfo [] = | |
Array.map | |
(fun (file : string) -> new FileInfo(file)) | |
filesInFolder | |
// Map those fileInfo objects to the file's size | |
let filesSize: int64 [] = | |
Array.map | |
(fun (info : FileInfo) -> info.Length) | |
fileInfos | |
// Total file sizes | |
let totalSize = Array.sum filesSize | |
//return | |
totalSize | |
//another better but ugly solution | |
let uglySizeOfFolder folder = | |
Array.sum | |
(Array.map | |
(fun (info: FileInfo)-> info.Length) | |
(Array.map | |
(fun file -> new FileInfo(file)) | |
(Directory.GetFiles( | |
folder, "*.*", | |
SearchOption.AllDirectories)))) | |
//nice solution | |
let sizeOfFolderPiped folder = | |
let getFiles path = | |
Directory.GetFiles(path, "*.*", SearchOption.AllDirectories) | |
let totalSize = | |
folder | |
|> getFiles | |
|> Array.map (fun file -> new FileInfo(file)) | |
|> Array.map (fun info -> info.Length) | |
|> Array.sum | |
totalSize | |
//pipe-forward operator | |
["Pipe"; "Forward"] |> List.iter (fun s -> printfn "s has length %d" s.Length) | |
//forward composition operator, folder size example | |
let sizeOfFolderComposed = | |
let getFiles folder = | |
Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories) | |
getFiles | |
>> Array.map (fun file -> new FileInfo(file)) | |
>> Array.map (fun info -> info.Length) | |
>> Array.sum | |
sizeOfFolderComposed <| (Environment.GetFolderPath <| Environment.SpecialFolder.MyDocuments) | |
let square2 x = x*x | |
let toString (x:int) = x.ToString() | |
let strLen (x:string) = x.Length | |
let lenOfSquare = square2 >> toString >> strLen | |
square2 12 | |
lenOfSquare 12 | |
let square3 x = x*x | |
let negate2 x = -x | |
// Using (>>) negates the square | |
(square3 >> negate2) 10 | |
(* | |
What we really want is the square of the negation | |
*) | |
(square3 << negate2) 10 | |
//filtering lists | |
[[1]; [];[4;5;6];[3;4];[];[];[];[9]] | |
|> List.filter (not << List.isEmpty) | |
// Define a literal value | |
[<Literal>] | |
let Bill = "Bill Gates" | |
// Match against literal values | |
let greet name = | |
match name with | |
| Bill -> "Hello Bill!" | |
| x -> sprintf "Hello, %s " x | |
greet "Bill G." | |
greet "Bill Gates" | |
// High/Low game | |
open System | |
let highLowGame() = | |
let rng = new Random() | |
let secretNumber = rng.Next() % 100 | |
let rec highLowGameStep() = | |
printfn "Gues the secert number: " | |
let guessStr = Console.ReadLine() | |
let guess = Int32.Parse(guessStr) | |
match guess with | |
| _ when guess > secretNumber | |
-> printfn "The secret number is lower." | |
highLowGameStep() | |
| _ when guess = secretNumber | |
-> printfn "You have guessed correctly" | |
() | |
| _ when guess < secretNumber | |
-> printfn "The secret number is higher." | |
highLowGameStep() | |
//begin the game | |
highLowGameStep() | |
highLowGame | |
// Discriminated union for a card's suit | |
type Suit = | |
| Heart | |
| Diamond | |
| Spade | |
| Club | |
// Discriminated union for playing cards | |
type PlayingCard = | |
| Ace of Suit | |
| King of Suit | |
| Queen of Suit | |
| Jack of Suit | |
| ValueCard of int * Suit | |
member this.Value = | |
match this with | |
| Ace(_) -> 11 | |
| King(_) | Queen(_) | Jack(_) -> 10 | |
| ValueCard(x, _) when x <= 10 && x >= 2 | |
-> x | |
| ValueCard(_) -> failwith "Card has an invalid value!" | |
let highCard = Ace(Spade) | |
let highCardValue = highCard.Value | |
//Use a list comprehension to generate a deck of cards | |
let deckOfCards = | |
[ | |
for suit in [Spade; Club; Heart; Diamond] do | |
yield Ace(suit) | |
yield King(suit) | |
yield Queen(suit) | |
yield Jack(suit) | |
for value in 2..10 do | |
yield ValueCard(value, suit) | |
] | |
// program statements | |
type Statement = | |
| Print of string | |
| Sequence of Statement * Statement | |
| IfStmt of Expression * Statement * Statement | |
// Program expressions | |
and Expression = | |
| Integer of int | |
| LessThan of Expression * Expression | |
| GreaterThan of Expression * Expression | |
(* | |
if (3 >1) print "aaa" | |
else | |
print "bbb" | |
*) | |
let program = | |
IfStmt( | |
GreaterThan(Integer(3), Integer(1)), | |
Print("£ is greater than 1"), | |
Sequence( | |
Print("3 is not"), | |
Print("greater than 1") | |
) | |
) | |
program | |
//binary tree using discriminated union | |
type BinaryTree = | |
| Node of int * BinaryTree * BinaryTree | |
| Empty | |
let rec printInOrder tree = | |
match tree with | |
| Node (data, left, right) -> | |
printInOrder left | |
printfn "Node %d" data | |
printInOrder right | |
| Empty -> () | |
let binTree = | |
Node(2, | |
Node(1, Empty, Empty), | |
Node(4, | |
Node(3, Empty, Empty), | |
Node(5, Empty, Empty) | |
) | |
) | |
printInOrder binTree | |
// Describe a pair of cards in a game of poker | |
let describeHoleCards cards = | |
match cards with | |
| [] | [_] | |
-> failwith "Too few cards." | |
| cards when List.length cards > 2 | |
-> failwith "Too many cards." | |
| [Ace(_); Ace(_)] -> "Pocket Rockets" | |
| [King(_); King(_)] -> "Cowboys" | |
| [ValueCard(2, _); ValueCard(2, _)] -> "Ducks" | |
| [Queen(_); Queen(_)] | |
| [Jack(_); Jack(_)] | |
-> "Pair of face cards" | |
| [ValueCard(x, _); ValueCard(y, _)] when x = y | |
-> "A pair" | |
| [first; second] | |
-> sprintf "Tw cards: %A and %A" first second | |
let hand1 = [Queen(Club); Queen(Club)] | |
describeHoleCards hand1 | |
let hand2 = [Ace(Spade)] | |
describeHoleCards hand2 | |
let hand3 = [ValueCard(12,Club); ValueCard(12, Heart)] | |
describeHoleCards hand3 | |
type Employee = | |
| Manager of string * Employee list | |
| Worker of string | |
let rec printOrganization worker = | |
match worker with | |
| Worker(name) -> printfn "Employee %s" name | |
// Manager with a worker list with one element | |
| Manager(managerName, [Worker(employeeName)]) | |
-> printfn "Manager %s with worker %s" managerName employeeName | |
// Manager with a worker list of two employees | |
| Manager(managerName, [Worker(emplName1); Worker(emplName2)]) | |
-> printfn "Manager %s with two workers %s %s" managerName emplName1 emplName2 | |
// Manager with a list of workers | |
| Manager(managerName, workers) | |
-> printfn "Manager %s with workers ... " managerName | |
workers |> List.iter printOrganization | |
let company = Manager("Tom", [Worker("Pam"); Worker("Stuart")]) | |
printOrganization company | |
let company2 = Manager("Tom", [Worker("Pam"); Worker("Stuart"); Worker("Martin")]) | |
printOrganization company2 | |
//Define a record type | |
type PersonRec = { First : string; Last: string; Age : int} | |
//Construct a record | |
let steve = {First = "Steve"; Last ="Holt"; Age = 12} | |
//Use .field to access record fields | |
steve.First | |
//Clonning | |
type Car = {Make : string; Model : string; Year : int} | |
let thisYear's = {Make = "Fsharp"; Model = "Luxury Sedan"; Year = 2012} | |
let nextYear's = {thisYear's with Year = 2013} | |
// type inference for records | |
type Point = {X :float; Y:float} | |
// Distance between two points | |
let distance (pt1 : Point) (pt2 : Point) = | |
let square x = x * x | |
sqrt <| square (pt1.X - pt2.X) + square (pt1.Y - pt2.Y) | |
// Add a property to a record type Vector | |
type Vector = | |
{ X : float; Y:float; Z:float} | |
member this.Length = | |
sqrt <| this.X ** 2.0 + this.Y ** 2.0 + this.Z ** 2.0 | |
let v = { X = 10.0; Y = 20.0; Z = 30.0} | |
v.Length | |
//Define two lazy values | |
let x1 = Lazy<int>.Create(fun () -> printfn "Evaluating x ..."; 10) | |
let y1 = lazy (printfn "Evaluating y ..."; x1.Value + x1.Value) | |
//Directly requesting y's value will force its evaluation | |
y1.Value | |
//Again? | |
y1.Value | |
//Sequence of all positive integers - lazy notation | |
let allPositiveIntsSeq = | |
seq { for i in 1 .. System.Int32.MaxValue do yield i} | |
allPositiveIntsSeq | |
//Sequence with a side effect | |
let noisyAlphabet = | |
seq { | |
for c in 'A' .. 'Z' do | |
printfn "Yielding %c ..." c | |
yield c | |
} | |
let fifthLetter = Seq.nth 4 noisyAlphabet | |
open System.IO | |
//all files under a folder | |
let rec allFilesUnder basePath = | |
seq{ | |
//Yield all files in the base folder | |
yield! Directory.GetFiles(basePath) | |
//Yield all files in its sub folders | |
for subdir in Directory.GetDirectories(basePath) do | |
yield! allFilesUnder subdir | |
} | |
open System | |
allFilesUnder <| (Environment.GetFolderPath <| Environment.SpecialFolder.MyDocuments) | |
|> Seq.length | |
// Sequence of random numbers | |
open System | |
let randomSequence = | |
seq { | |
let rng = new Random() | |
while true do | |
yield rng.Next() | |
} | |
randomSequence |> Seq.take 3 | |
//Generate the next element of the Fibonacci sequence | |
//given the previous two elements. To be used with Seq.unfold | |
let nextFibUnder100(a,b) = | |
if a + b > 100 then | |
None | |
else | |
let nextValue = a + b | |
Some(nextValue, (nextValue, a)) | |
let fibsUnder_100 = Seq.unfold nextFibUnder100 (0,1) | |
fibsUnder_100 |> Seq.toList | |
//Print odd numbers under 10 | |
let oddsUnderN n = seq { for i in 1 .. 2 .. n -> i} | |
Seq.iter (printfn "%d") (oddsUnderN 10) | |
Seq.iter (printfn "%A") <| oddsUnderN 10 | |
//Sequence of words (Arrays are compatible with sequences) | |
let words = "The quick brown fox jumped over the lazy dog".Split([| ' ' |]) | |
//map strings to string, length tuples | |
words |> Seq.map(fun word -> word, word.Length) | |
//fold for reduce | |
Seq.fold (+) 0 <| seq { 1 .. 100 } | |
//query expressions | |
open System.Diagnostics | |
let activeProcCount = | |
query { | |
for activeProc in Process.GetProcesses() do | |
count | |
} | |
let memoryHog = | |
query { | |
for activeProcess in Process.GetProcesses() do | |
sortByDescending activeProcess.WorkingSet64 | |
head | |
} | |
printfn "'%s' has a working set of :\n%d bytes" memoryHog.MainWindowTitle memoryHog.WorkingSet64 | |
//returns all processes displaying UI | |
let windowedProcesses = | |
query { | |
for activeProcess in Process.GetProcesses() do | |
where (activeProcess.MainWindowHandle <> nativeint 0) | |
select activeProcess | |
} | |
let printProcessList procSeq = | |
Seq.iter (printfn "%A") <| procSeq | |
printProcessList windowedProcesses | |
let isChromeRunning = | |
query { | |
for windowedProc in Process.GetProcesses() do | |
select windowedProc.ProcessName | |
contains "chrome" | |
} | |
//|> Seq.toList | |
isChromeRunning | |
let numOfServiceProcesses = | |
query { | |
for activeProcess in Process.GetProcesses() do | |
where (activeProcess.MainWindowHandle <> nativeint 0) | |
select activeProcess | |
count | |
} | |
numOfServiceProcesses | |
//using district operator | |
let oneHundredNumberUnderfifty = | |
let rnd = new Random() | |
seq { | |
for i = 1 to 100 do | |
yield rnd.Next() % 50 | |
} | |
let districtNumbers = | |
query { | |
for randomNumber in oneHundredNumberUnderfifty do | |
select randomNumber | |
distinct | |
} |> Seq.length | |
//Number of threads used by the process with the most threads | |
let highestThreadCount = | |
query { | |
for proc in Process.GetProcesses() do | |
maxBy proc.Threads.Count | |
} | |
//active processes sorted by whether or not they have a UI, then by name | |
let sortedProc = | |
query { | |
for proc in Process.GetProcesses() do | |
let isWindowed = proc.MainWindowHandle <> nativeint 0 | |
sortBy isWindowed | |
thenBy proc.ProcessName | |
select proc | |
} |> Seq.toList | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment