Skip to content

Instantly share code, notes, and snippets.

@MartinBodocky
Created April 1, 2014 00:23
Show Gist options
  • Save MartinBodocky/9905278 to your computer and use it in GitHub Desktop.
Save MartinBodocky/9905278 to your computer and use it in GitHub Desktop.
Chapter 2-3
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