- .Net Core Installed
- Ionide extension
- Bracket Pair Colorizer 2
- Create a project
dotnet new console -lang F#
- Running a project
dotnet run
- Debugging
- Use the Ionide extension
- Can set up VS code debugging files, but annoying
- Last line in a function is what is returned
- Array: array.[0] (annoying .)
- Format specifiers are strongly typed
printfn "Hello %s from my F# program" person
- Minimize mutable variables
let mutable person = "Anonymous Person"
- When to use type annotations?
- Type inference is pretty good for the most part
- Type methods usually require type annotations
let fromStringOr (d: float) (s: string) : float = s |> tryFromString |> Option.defaultValue d
- Example, not really needed
- When adding files, use ionide ext
- My guess, is you need to do reference stuff too
- File order matters in compilation
- Records vs Anonymous Records
- {...} means record type
- {|...|} means anonymous record
- You'd use anonymous records when returning tupules
- Gives you named fields to use
- Arrays are mutable
- Arguments often have no brackets
- Separated by spaces
let arrayIter argv = Array.iter sayHello argv printfn "Nice to meet you"
- This serves a purpose: forward piping
- Forward pipe operator
argv |> Array.filter isValid |> Array.iter sayHello
- Modules are used to associate record types w/ functionality
- Use the same name b/t a record and a module
type Student =
{
Name: string
Id: string
MeanScore: float
MinScore: float
MaxScore: float
}
module Student =
let fromString (s: string) =
let elements = s.Split('\t')
let name = elements.[0]
let id = elements.[1]
let scores =
elements
|> Array.skip 2
|> Array.map float
let meanScore = scores |> Array.average
let minScore = scores |> Array.min
let maxScore = scores |> Array.max
{
Name = name
Id = id
MeanScore = meanScore
MinScore = minScore
MaxScore = maxScore
}
let printSummary (student: Student) =
printfn "%s\t%s\t%0.1f\t%0.1f\t%0.1f" student.Name student.Id student.MeanScore student.MinScore student.MaxScore
-
Curried parameters
let fromStringOr d s: float = s |> tryFromString |> Option.defaultValue d
- Function parameters which support partial application
- When an argument is supplied, the result is a function that expects any remaining params
- When all args have been supplied, the function returns a result
let add a b = a + b let c = add 2 3 // not an error // partial application of curried function let d = add 2 let e = d 4
- This causes lots of bugs due to it not throwing an error, but just returning a function
-
Tupule Parameters
let fromStringOr (d, s): float = s |> tryFromString |> Option.defaultValue d
- Discriminated Unions
type TestResult =
| Absent
| Excused
| Voided
| Scored of float
- Match Expressions
let tryEffectiveScore (testResult: TestResult) =
match testResult with
| Absent -> Some 0.0
| Excused
| Voided -> None
| Scored score -> Some score
-
The default case
let nameParts (s: string) = let elements = s.Split(',') match elements with | [|surname; givenName|] -> surname.Trim(), givenName.Trim() | _ -> raise (System.FormatException(sprintf "Invalid name format: \"%s\"" s))
-
Use rarely as when you add a new item in the union, you may forget to add a handle in the match expression
- Which would then hit the default case
let todayIsThursday() =
DateTime.Now.DayOfWeek = DayOfWeek.Thursday
let isEven x =
x % 2 = 0
// The code can be complex
let evenNums =
[|
if todayIsThursday() then 42
for i in 1..9 do
let x = i * i
if x |> isEven then
x // implicit yield
999
|]
- Similar to array, but it doesn't store everything like an Array
- Type IEnumerable
- Generates values on demand
let totalSeq =
seq { for i in 1..1000 -> i * i }
|> Seq.sum
- If you consume them multiple times, you'd be calculating them multiple times
let totalSeq = seq { for i in 1..1000 -> i * i } |> Seq.sum |> seq.cache
Seq.toArray
- When to use a sequence?
- Collection only exists to be summarized or piped
- Long in theory but only some elements accessed
- When to use an array?
- Iterated over/consumed multiple times
- Elements access by index
- You need to test your program w/ realistic amounts of data
- Similar to arrays, but immutable
- It's also a linked list, not a contiguous block of memory
- Nuget
- Option.map, Option.bind
- SAFE Stack and Fable for Web UI development