Created
April 4, 2014 14:47
-
-
Save MartinBodocky/9976173 to your computer and use it in GitHub Desktop.
Chapter 4-6
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
//Mutable record types | |
open System | |
type MutableCar = | |
{ | |
Make : string | |
Model : string | |
mutable Miles : int | |
} | |
let driveForAReason (car : MutableCar) : unit = | |
let rng = new Random() | |
car.Miles <- car.Miles + rng.Next() % 10000 | |
let kitt = { Make = "Pontiac"; Model = "Trans Am"; Miles = 0} | |
driveForAReason kitt | |
kitt | |
//Unit of measures | |
[<Measure>] | |
type fahrenheit | |
let printTemperature (temp : float<fahrenheit>) = | |
if temp < 32.0<_> then | |
printfn "Bellow Freezing" | |
elif temp > 100.0<_> then | |
printfn "Hot!" | |
else | |
printfn "Scorching!" | |
let seatle = 59.0<fahrenheit> | |
printTemperature seatle | |
[<Measure>] | |
type celsius | |
let cambridge : float<celsius> = 18.0<celsius> | |
printTemperature cambridge | |
//Define measure for meter | |
[<Measure>] | |
type m | |
// Mutliplication | |
1.0<m> * 1.0<m> | |
//Division | |
1.0<m> / 1.0<m> | |
//Define seconds and hertz | |
[<Measure>] | |
type s | |
[<Measure>] | |
type Hz = s ^ -1 | |
3.0<s^-1> = 3.0<Hz> | |
//Adding methods to unit of measures | |
[<Measure>] | |
type far = | |
static member ConvertToCel(x: float<far>) = | |
(5.0<cel> / 9.0<far>) * (x - 32.0<far>) | |
and [<Measure>] cel = | |
static member ConvertToFar (x: float<cel>) = | |
(9.0<far> / 5.0<cel> * x) + 32.0<far> | |
far.ConvertToCel(100.0<far>) | |
//UnitSymbols contains the abbreviated versions of SI units | |
open Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols | |
open Microsoft.FSharp.Data.UnitSystems.SI.UnitNames | |
//in candela | |
let flashlightIntensity = 80.0<cd> | |
let weightofyou = 85.0<kilogram> | |
//generic units of measure | |
let squareMeter (x : float<m>) = x*x | |
let genericSquare (x : float<_>) = x*x | |
squareMeter 1.0<m> | |
genericSquare 1.0<m/s> | |
//Represents a point respecting the unit of measure | |
type Point< [<Measure>] 'u> (x : float<'u>, y : float<'u>) = | |
member this.X = x | |
member this.Y = y | |
member this.UnitlessX = float x | |
member this.UnitlessY = float y | |
member this.Length = | |
let sqr x = x * x | |
sqrt <| sqr this.X + sqr this.Y | |
override this.ToString() = | |
sprintf "{%f, %f}" this.UnitlessX this.UnitlessY | |
let p = new Point<m>(10.0<m>, 10.0<m>) | |
p.Length | |
//using the array comprehension syntax | |
let perfectSquares = [| for i in 1..7 -> i * i |] | |
//manually decaled | |
let perfectSquares2 = [|12;321;434;656;787;|] | |
//indexing | |
perfectSquares2.[0] | |
//ROT 13 encryption in f# | |
open System | |
//Encrypt a letter using ROT13 | |
let rot13Encrypt (letter : char) = | |
// Move the letter forward 13 places in the alphabet | |
if Char.IsLetter(letter) then | |
let newLetter = | |
(int letter) | |
|> (fun letterIdx -> letterIdx - (int 'A')) | |
|> (fun letterIdx -> (letterIdx + 13) % 26) | |
|> (fun letterIdx -> letterIdx + (int 'A')) | |
|> char | |
newLetter | |
else | |
letter | |
//Loop through each letter array element, encrypting each letter | |
let encryptText (text: char[]) = | |
for idx = 0 to text.Length - 1 do | |
let letter = text.[idx] | |
text.[idx] <- rot13Encrypt letter | |
let text = Array.ofSeq "THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG" | |
printfn "Original = %s" <| new String(text) | |
encryptText(text) | |
printfn "Encrypted = %s" <| new String(text) | |
//A unique trait of ROT13 is that to decrypt, simply encrypt again | |
encryptText(text) | |
printfn "Decrypted = %s"<| new String(text) | |
//Array slices | |
let daysOfWeek = Enum.GetNames(typeof<DayOfWeek>) | |
//Standard array slice, elements 2 through 4 | |
daysOfWeek.[2..4] | |
//Just specify lower bound, elements 4 to the end | |
daysOfWeek.[4..] | |
//Just specify an upper bound, elements 0 to 2 | |
daysOfWeek.[..2] | |
//Specify no bounds | |
daysOfWeek.[*] | |
// Initialize an array of sin-wave elements | |
let divisions = 4.0 | |
let twoPi = 2.0 * Math.PI | |
Array.init(int divisions) (fun i -> float i * twoPi / divisions) | |
//Construct empty arrays | |
let emptyIntArray : int[] = Array.zeroCreate 3 | |
let emptyStringArray : string[] = Array.zeroCreate 3 | |
//Pattern matching in array | |
let describeArray arr = | |
match arr with | |
| null -> "The array is null" | |
| [| |] -> "The array is empty" | |
| [| x |] -> "The array has one element" | |
| [| x ; y|] -> "The array has two elements" | |
| a -> sprintf "The array has %d elements, %A" a.Length a | |
describeArray null | |
describeArray [||] | |
describeArray [|1..4|] | |
describeArray [| (12,3) |] | |
//array partition | |
let isGreaterThan x = (x>10) | |
[| 5.. 15 |] |> Array.partition isGreaterThan | |
// tryFind and tryFindIndex | |
let rec isPowerOfTwo x = | |
if x = 2 then | |
true | |
elif x % 2 = 1 then | |
false | |
else | |
isPowerOfTwo (x/2) | |
[| 1; 7; 13; 64; 32|] |> Array.tryFind isPowerOfTwo | |
[| 1; 7; 13; 64; 32|] |> Array.tryFindIndex isPowerOfTwo | |
// aggregate operators | |
let vowels = [| 'a'; 'e'; 'i'; 'o';'u' |] | |
Array.iteri (fun idx chr -> printfn "viwel.[%d] = %c" idx chr) vowels | |
//Rectangular arrays | |
// Create a 3x3 array | |
let idenityMatrix : float[,] = Array2D.zeroCreate 3 3 | |
idenityMatrix.[0,0] <- 1.0 | |
idenityMatrix.[1,1] <- 1.0 | |
idenityMatrix.[2,2] <- 1.0 | |
idenityMatrix | |
// Create a jagged array | |
let jaggedArray : int [][] = Array.zeroCreate 3 | |
jaggedArray.[0] <- Array.init 1 (fun x -> x) | |
jaggedArray.[1] <- Array.init 2 (fun x -> x) | |
jaggedArray.[2] <- Array.init 3 (fun x -> x) | |
jaggedArray | |
//Create a List<_> of planets | |
open System.Collections.Generic | |
let planets = new List<string>() | |
planets.Add("Mercury") | |
planets.Add("Venus") | |
planets.Add("Earth") | |
planets.Add("Mars") | |
planets.Add("Pluto") | |
planets.AddRange([| "Neptune"; "Saturn"|]) | |
planets.Count | |
planets.Remove("Pluto") | |
planets | |
//Using a dictionary | |
//Atom Mass Units | |
[<Measure>] | |
type amu | |
type Atom = {Name: string; Weight: float<amu>} | |
open System.Collections.Generic | |
let periodicTable = new Dictionary<string, Atom>() | |
periodicTable.Add("H", {Name = "Hydrogen";Weight = 1.0079<amu>}) | |
periodicTable.Add("He", {Name = "Helium";Weight = 4.0026<amu>}) | |
periodicTable.Add("Li", {Name = "Lithium";Weight = 6.9410<amu>}) | |
periodicTable.Add("Be", {Name = "Beryllium";Weight = 9.0122<amu>}) | |
periodicTable.Add("B", {Name = "Boron";Weight = 10.811<amu>}) | |
//Lookup an element | |
let printElement name = | |
if periodicTable.ContainsKey(name) then | |
let atom = periodicTable.[name] | |
printfn "Atom with symbol '%s' has weight %A." atom.Name atom.Weight | |
else | |
printfn "Error. No atom found" | |
let printElement2 name = | |
let (found, atom) = periodicTable.TryGetValue(name) | |
if found then | |
printfn "Atom with symbol '%s' has weight %A." atom.Name atom.Weight | |
else | |
printfn "Error. No atom found" | |
// loops | |
for i=1 to 5 do printfn "%A" i | |
for i=5 downto 0 do printfn "%A" i | |
//for loops can do pattern matching :) | |
type Pet = | |
| Cat of string * int | |
| Dog of string | |
let famousPets = [ Dog("Lassie"); Cat("Felix",9); Dog "Rin Tin Tin"] | |
for Dog(name) in famousPets do | |
printfn "Dof : %s" name | |
// Pattern matching against types | |
let whatIs (x : obj) = | |
match x with | |
| :? string as s -> printfn "%s is string" s | |
| :? int as i -> printfn "%d is integer" i | |
| :? list<int> as l -> printfn "%A is list of integer" l | |
| _ -> printfn "%A is another type %A" x <| x.GetType().Name | |
whatIs [1..5] | |
whatIs "aaa" | |
whatIs 1212 | |
whatIs 12.3<joule> | |
//Extend the System.Int32 AKA int type | |
type System.Int32 with | |
member this.ToHexString() = sprintf "0x%x" this | |
(1094).ToHexString() | |
type Point< [<Measure>] 'u> with | |
member this.ToMyLength() = this.Length | |
let app = p.ToMyLength() | |
app |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment