What’s this? #
Notes on F# as I learn features. This sample, I’ve created a program that counts repeating charaters in a string. I break it down to Managers, Engines, Contracts so that it somewhat follows the IDesign nomenclature. Since this is my first foray into F#, this will likely not be a great example, but is more of a testing ground.
The Engines are called by the Managers. Contracts can be shared at all levels.
Getting intellisense to work #
I think adding .vscode\settings.json was needed to get code completion for built-in types.
{
"FSharp.workspacePath": "./Fsharp.slnx",
}
Files #
The file tree for this code.
.
├── Alpha.Contracts
│ ├── Alpha.Contracts.fsproj
│ └── Types.fs
├── Alpha.Engines
│ ├── Alpha.Engines.fsproj
│ └── StringProcessor.fs
├── Alpha.Managers
│ ├── Alpha.Managers.fsproj
│ └── StringManager.fs
├── AppConsole
│ ├── AppConsole.fsproj
│ └── Program.fs
└── Fsharp.slnx
Types.fs #
namespace Alpha.Contracts
type LetterStat = {
Letter: char
Rank: int
Count: int
}
StringProcessor.fs #
namespace Alpha.Engines
open Alpha.Contracts
module StringProcessor =
let hello name fromTown =
$"Hello %s{name}, from %s{fromTown}"
let toCharList (input: string) =
input.ToCharArray() |> Seq.toList
let charAcc (input: char) (position: int) (acc: LetterStat list) =
let foundChar = acc |> List.tryFind (fun c -> c.Letter = input)
if foundChar = None then
let newEntry = { Letter = input; Rank = position; Count = 1}
acc @ [newEntry] // append
else
let newCount = foundChar.Value.Count + 1
let updated = { foundChar.Value with Count = newCount }
List.except [foundChar.Value] acc @ [updated]
let findCharReferences (input: string) =
let chars = toCharList input
// fold is a fundamental concept.
let output = chars |> List.fold (
fun (idx: int, acc: LetterStat list)
curr -> idx + 1, charAcc curr idx acc) (0, [])
snd output // gets the second element of the tuple
StringManager.fs #
namespace Alpha.Managers
open Alpha.Engines
module StringManager =
let hello name =
printfn "Hello %s"
let findCharReferences = StringProcessor.findCharReferences
let findFirstNonRepeatingChar input =
let result = StringProcessor.findCharReferences input
result |> List.filter(fun x -> x.Count = 1) |>
List.sortBy(fun x -> x.Rank) |> List.tryHead
Program.fs #
// For more information see https://aka.ms/fsharp-console-apps
open Alpha.Managers
open Alpha.Contracts
let inputStr = "tottoem"
let printOut (input : LetterStat list) =
input |> List.iter (fun item ->
printfn $"{item.Letter}: Count: {item.Count} Rank: {item.Rank} ")
let result = StringManager.findCharReferences(inputStr)
result |> printOut
printfn "----------"
let printOutSingle (input : option<LetterStat>) =
if input.IsSome then
[input.Value] |> printOut
else
printfn "no repeating chars found"
let result2 = StringManager.findFirstNonRepeatingChar(inputStr)
printOutSingle result2