Last active
July 14, 2023 13:04
-
-
Save jkone27/47ac31e05afd756ffda5eb697308a166 to your computer and use it in GitHub Desktop.
learn F# in one go
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
(* | |
module ---> like a static class in C# | |
open (like using or using static in C#) --> just open a namespace or module | |
let ----> like var but used both for varialbles and functions, any binding is done with let, last value in scope is the result | |
type ---> custom/user-defined types , records, classes, discriminated unions, interfaces ecc.. | |
task ---> like async Task<T> in C#, let! is await, return! is return await, return is return | |
*) | |
namespace Some.Test | |
open System | |
open System.Collections.Generic | |
module SomeModule = | |
let x = 5 | |
// we can enforce type signatures to correct the compiler if needed in special cases | |
let xWithTypeConstraint: int = 5 | |
// in true functional languages everything is a "function" | |
// or better all is an expression binding | |
// so you can bind functions to names | |
let mySumBinding = (+) | |
let sumResult = mySumBinding 1 2 | |
// all functions are curried by default, it means you can pass just one argument | |
// and a new function is returned back to you with the missing argument only | |
// this is useful but can also be tricky | |
// if you don't check that you have passed all arguments, always check what type is inferred | |
// by hovering with your mouse, or you can enforce the type constraint if needed | |
let xPlusFive = (+) 5 // this function is `x + 5` | |
let r = xPlusFive 10 // gives 15 | |
let parseStringToInt = | |
(int) "5" // same as Int32.Parse | |
+ | |
int "5" // equivalent | |
+ | |
("5" |> int) // equivalent | |
let scopedVar = | |
let someScopedVal = 5 | |
5 + 1 // last value in a scope always the return value! | |
let procedure () = | |
printfn "hello procedural world! void is called " | |
() // return unit/void | |
let list = | |
[ 1 ; 2; 3 ] // in line use ; separtor for stuff | |
@ //concat lists | |
[ | |
4 // multiline does not need ; separator | |
5 | |
6 | |
] | |
let arrayOfInts = [| 1 ; 2; 3 |] | |
// List<T> in C# is ResizeArray<T> in F#, default collections in F# are immutable | |
let convertToDotnetList = | |
arrayOfInts | |
|> ResizeArray | |
let convertToDotnetIDictionary = | |
[ | |
"A",1 | |
"B",2 | |
"C",3 | |
] | |
|> dict | |
let dotnetDict = new Dictionary<string,string>() | |
// Seq module manipulates IEnumerable (seq in F#) | |
let enumerableManipulation = | |
list | |
|> Seq.map (fun s -> s + 1) // like Select in Linq | |
|> Seq.filter (fun s -> s > 0) // like .Where in Linq | |
|> Seq.collect (fun s -> [ s ] ) // like .Flatten in Linq | |
|> Seq.fold (fun s a -> s + a) 0 // like .Aggregate in Linq | |
// similar function exist for all main collection modules Seq, List, Array, Map, ecc | |
let tuple = | |
1 , 2, "hello", [ "hey" ; "hi" ] | |
let someFunction firstArg secondArg = | |
firstArg + secondArg | |
|> sprintf "result: %i" | |
module AnotherModule = | |
let someResult = | |
SomeModule.someFunction 1 2 | |
let someAsyncMethod() = task { | |
return 5 | |
} | |
let dotnetAsyncAwait = task { | |
let! awaitedValue = someAsyncMethod() | |
return awaitedValue + 5 | |
} | |
module FunctionalTypes = | |
// records are like named tuples, similar to C# pocos/java pojos but immutable | |
type Person = { | |
Name: string ; Surname : string | |
Age: int // like list, no need to add ; when you go to a new line | |
} | |
let john = { Name = "john" ; Surname = "hehe" ; Age = 1 } | |
let olderJohn = { john with Age = 199 } | |
// F# type extensions, also regular extension methods are available (see online) | |
type Person with | |
member this.Hello() = $"hello i am {this.Name}" | |
// this is a simple Enum like in C#, note that a value has to be assigned to it, to make it an enum | |
type EnumValues = | |
| First = 1 | |
| Second = 2 | |
| Third = 99 | |
// this one is not an enum but in many cases can be used to a similar extent | |
// without risking to change underlying representations by mistake | |
// to string gives you the string representation already like "First" | |
type SimpleDu = | |
| First | |
| Second | |
| Third | |
// a string is not an email, this is a nice way to wrap a type i a single case Discriminated union | |
// and do a correct domain modeling | |
type OneCaseDu = Email of string | |
// Discriminated unions can model domains better than classes and inheritance | |
// at compile time (static time) instead of "runtime" and objects with runtime method dispatch | |
type Employee = | |
| CEO of Person * yearsInTheCompany: int | |
| Manager of Person | |
| CFO of Person | |
| CTO of Person * techSkills : string list | |
| Developer of Person | |
| ProductOwner of Person | |
| CleaningPersonel of Person | |
// here different kinds of pattern matching in action | |
let hireNewPerson person salary = | |
match person with | |
| { Age = age } when age > 18 -> | |
if salary > 100.000m then | |
Employee.CEO(person, 0) | |
else if salary > 50.000m then | |
Employee.CTO(person, ["java"; "springboot"; "scrum"]) | |
else | |
Employee.CleaningPersonel(person) | |
|_ -> | |
failwith "we cannot hire people with < 18 years of age!" | |
let johnCeo = hireNewPerson olderJohn 400.000m | |
module ObjectOrientedProgramming = | |
type SomeClass() = | |
class | |
end | |
type ICoolInterface = | |
interface | |
end | |
type IRealInterface = | |
abstract member Do : unit -> int | |
abstract member Something : string * string -> int | |
type OtherClass(privateReadonly: int) = | |
let privateReadonlyInternal = 5 | |
do | |
printf "constructor stuff" | |
member this.Method(parameter) = | |
privateReadonly + privateReadonlyInternal * parameter | |
interface ICoolInterface // implement empty interface | |
interface IRealInterface with | |
member this.Do() = 5 | |
member this.Something(name, surname) = 4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment