[
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 Adelar da Silva Queiróz\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# F# Cheatsheet 🔷\n\nAn updated cheatsheet for [F#](https://fsharp.org/).\n\nThis cheatsheet glances over some of the common syntax of F#.\n\nContents\n--------\n- [Comments](#Comments)  \n- [Strings](#Strings)  \n- [Types and Literals](#TypesAndLiterals)  \n- [Printing Things](#PrintingThings)  \n- [Loops](#Loops)  \n- [Values](#Values)  \n- [Functions](#Functions)  \n- [Pattern Matching](#PatternMatching)  \n- [Collections](#Collections)  \n- [Records](#Records)  \n- [Discriminated Unions](#DiscriminatedUnions)  \n- [Exceptions](#Exceptions)  \n- [Classes and Inheritance](#ClassesAndInheritance)  \n- [Interfaces and Object Expressions](#InterfacesAndObjectExpressions)  \n- [Casting and Conversions](#CastingAndConversions)  \n- [Active Patterns](#ActivePatterns)  \n- [Compiler Directives](#CompilerDirectives)  \n- [Acknowledgments](#Acknowledgments)  \n\n-------------------\n\n<a name=\"Comments\"></a>Comments\n--------\n\nLine comments start from `//` and continue until the end of the line. Block comments are placed between `(*` and `*)`.\n\n```fsharp\n// And this is line comment\n(* This is block comment *)\n```\n\n[XML doc comments](https://docs.microsoft.com/dotnet/fsharp/language-reference/xml-documentation) come after `///` allowing us to use XML tags to generate documentation.    \n    \n```fsharp\n/// The `let` keyword defines an (immutable) value\nlet result = 1 + 1 = 2\n```\n\n<a name=\"Strings\"></a>Strings\n-------\n\nThe F# `string` type is an alias for `System.String` type. See [Strings](https://docs.microsoft.com/dotnet/fsharp/language-reference/strings).\n\n```fsharp\n/// Create a string using string concatenation\nlet hello = \"Hello\" + \" World\"\n```\n\nUse *verbatim strings* preceded by `@` symbol to avoid escaping control characters (except escaping `\"` by `\"\"`).\n\n```fsharp\nlet verbatimXml = @\"<book title=\"\"Paradise Lost\"\">\"\n```\n\nWe don't even have to escape `\"` with *triple-quoted strings*.\n\n```fsharp\nlet tripleXml = \"\"\"<book title=\"Paradise Lost\">\"\"\"\n```\n\n*Backslash strings* indent string contents by stripping leading spaces.\n\n```fsharp\nlet poem = \n    \"The lesser world was daubed\\n\\\n     By a colorist of modest skill\\n\\\n     A master limned you in the finest inks\\n\\\n     And with a fresh-cut quill.\"\n```\n\n[Interpolated strings](https://docs.microsoft.com/dotnet/fsharp/language-reference/interpolated-strings) let you write code in \"holes\" inside of a string literal:\n\n```fsharp\nlet name = \"Phillip\"\nlet age = 30\nprintfn $\"Name: {name}, Age: {age}\"\n\nlet str = $\"A pair of braces: {{}}\"\nprintfn $\"Name: %s{name}, Age: %d{age}\" // typed\n```\n\n<a name=\"TypesAndLiterals\"></a>Types and Literals\n------------------------\n\nMost numeric types have associated suffixes, e.g., `uy` for unsigned 8-bit integers and `L` for signed 64-bit integer.\n\n```fsharp\nlet b, i, l, ul = 86uy, 86, 86L, 86UL\n\n// val ul: uint64 = 86UL\n// val l: int64 = 86L\n// val i: int = 86\n// val b: byte = 86uy\n```\n\nOther common examples are `F` or `f` for 32-bit floating-point numbers, `M` or `m` for decimals, and `I` for big integers.\n\n```fsharp\nlet s, f, d, bi = 4.14F, 4.14, 0.7833M, 9999I\n\n// val bi: System.Numerics.BigInteger = 9999\n// val d: decimal = 0.7833M\n// val f: float = 4.14\n// val s: float32 = 4.14f\n```\n\nSee [Literals](https://docs.microsoft.com/dotnet/fsharp/language-reference/literals) for complete reference.\n\n`and` keyword is used for definining mutually recursive types and functions:\n\n```fsharp\ntype A = \n  | Aaa of int \n  | Aaaa of C\nand C = \n  { Bbb : B }\nand B() = \n  member x.Bbb = Aaa 10\n```\n\nFloating point and signed integer values in F# can have associated [units of measure](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/units-of-measure), which are typically used to indicate length, volume, mass, and so on:\n\n```fsharp\n[<Measure>] type kg\nlet m1 = 10.0<kg>\nlet m2 = m1 * 2.0 // type inference for result \nlet add30kg m =   // type inference for input and output\n    m + 30.0<kg>\nadd30 2.0<kg>     // val it: float<kg> = 32.0\n```\n\n<a name=\"PrintingThings\"></a>Printing Things\n------------------------\n\nPrint things to console with `printfn`:\n\n```fsharp\nprintfn \"Hello, World\"\n\nprintfn $\"The time is {System.DateTime.Now}\"\n```\n\nYou can also use `Console.WriteLine`:\n```fsharp\nopen System\n\nConsole.WriteLine $\"The time is {System.DateTime.Now}\"\n```\n\nConstrain types with `%d`, `%s`, and print structured values with `%A`:\n\n```fsharp\nlet data = [1..10]\n\nprintfn $\"The numbers %d{1} to %d{10} are %A{data}\"\n```\n\nOmit holes and apply arguments:\n\n```fsharp\nprintfn \"The numbers %d to %d are %A\" 1 10 data\n```\n\nSee [Plaintext Formatting](https://docs.microsoft.com/dotnet/fsharp/language-reference/plaintext-formatting)\n\n<a name=\"Loops\"></a>Loops\n---------\n\n### for...in\n\n[For loops](https://docs.microsoft.com/dotnet/fsharp/language-reference/loops-for-in-expression):\n\n```fsharp\nlet list1 = [1; 5; 100; 450; 788]\n\nfor i in list1 do\n    printf \"%d\" i           // 1 5 100 450 788\n\nlet seq1 = seq { for i in 1 .. 10 -> (i, i * i) }\n\nfor (a, asqr) in seq1 do\n    // 1 squared is 1\n    // ...\n    // 10 squared is 100\n    printfn \"%d squared is %d\" a asqr\n\nfor i in 1 .. 10 do\n    printf \"%d \" i          // 1 2 3 4 5 6 7 8 9 10\n\n// for i in 10 .. -1 .. 1 do\nfor i = 10 downto 1 do\n    printf \"%i \" i          // 10 9 8 7 6 5 4 3 2 1\n\nfor i in 1 .. 2 .. 10 do\n    printf \"%d \" i             // 1 3 5 7 9\n\nfor c in 'a' .. 'z' do\n    printf \"%c \" c          // a b c ... z\n\n// Using of a wildcard character (_)\n// when the element is not needed in the loop.\nlet mutable count = 0\n\nfor _ in list1 do\n    count <- count + 1\n```\n\n### while...do\n\n[While loops](https://docs.microsoft.com/dotnet/fsharp/language-reference/loops-while-do-expression):\n\n```fsharp\nlet mutable mutVal = 0\nwhile mutVal < 10 do        // while (not) test-expression do\n    mutVal <- mutVal + 1\n```\n\n<a name=\"Values\"></a>Values\n------------------\n\nValues have different names based on length, called unit, single value and tuples.\n\n```fsharp\n// unit (no value)\nlet nothing = ()\n\n// single value\nlet single = 1 // same as `let single = (1)`\n```\n\nFunctions that return void in C# will return the unit type in F#.\n\nA *tuple* is a grouping of unnamed but ordered values, with lenght equal or bigger than 2 and possibly of different types:\n\n```fsharp\n// 2-tuples\nlet x = (1, \"Hello\")\n\n// 3-tuples\nlet y = (\"one\", \"two\", \"three\") \n\n// Tuple deconstruction\nlet (a', b') = x\nlet (c', d', e') = y\n\n// The first and second elements of a tuple can be obtained using `fst`, `snd`, or pattern matching:\nlet c' = fst (1, 2)\nlet d' = snd (1, 2)\n  \nlet print' tuple =\n    match tuple with\n    | (a, b) -> printfn \"Pair %A %A\" a b\n```\n\n<a name=\"Functions\"></a>Functions\n---------\n\nThe [`let`](https://docs.microsoft.com/dotnet/fsharp/language-reference/functions/let-bindings) keyword also defines named functions.\n\n```fsharp\nlet pi () = 3.14159 // function with no arguments. () is called unit type\npi ()               // it's necessary to use () to call the function\n\nlet negate x = x * -1 \nlet square x = x * x \nlet print x = printfn $\"The number is: %d{x}\"\n\nlet squareNegateThenPrint x = \n    print (negate (square x)) \n```\n\nDouble-backtick identifiers are handy to improve readability especially in unit testing:\n\n```fsharp\nlet ``square, negate, then print`` x = \n    print (negate (square x)) \n```\n\n### Pipe operator\n\nThe pipe operator `|>` is used to chain functions and arguments together:\n\n```fsharp\nlet squareNegateThenPrint x = \n    x |> square |> negate |> print\n```\n\nThis operator is essential in assisting the F# type checker by providing type information before use:\n\n```fsharp\nlet sumOfLengths (xs : string []) = \n    xs \n    |> Array.map (fun s -> s.Length)\n    |> Array.sum\n```\n\n### Composition operator\n\nThe composition operator `>>` is used to compose functions:\n\n```fsharp\nlet squareNegateThenPrint = \n    square >> negate >> print\n```\n  \n<a name=\"PatternMatching\"></a>Pattern Matching\n----------------\n\nPattern matching is primarily through `match` keyword;\n\n```fsharp\nlet rec fib n =\n    match n with\n    | 0 -> 0\n    | 1 -> 1\n    | _ -> fib (n - 1) + fib (n - 2)\n```\n\nUse `when` to create filters or guards on patterns:\n\n```fsharp\nlet sign x = \n    match x with\n    | 0 -> 0\n    | x when x < 0 -> -1\n    | x -> 1\n```\n\nPattern matching can be done directly on arguments:\n\n```fsharp\nlet fst (x, _) = x\n```\n\nor implicitly via `function` keyword:\n\n```fsharp\n/// Similar to `fib`; using `function` for pattern matching\nlet rec fib2 = function\n    | 0 -> 0\n    | 1 -> 1\n    | n -> fib2 (n - 1) + fib2 (n - 2)\n```\n\nSee [Pattern Matching](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching).\n\n<a name=\"Collections\"></a>Collections\n-----------\n\n### Lists\n\n[*Lists*](https://docs.microsoft.com/dotnet/fsharp/language-reference/lists) are immutable collection of elements of the same type.\n\n```fsharp\n// Lists use square brackets and `;` delimiter\nlet list1 = [\"a\"; \"b\"]\n\n// :: is prepending\nlet list2 = \"c\" :: list1\n\n// @ is concat    \nlet list3 = list1 @ list2   \n\n// Recursion on list using (::) operator\nlet rec sum list = \n    match list with\n    | [] -> 0\n    | x :: xs -> x + sum xs\n```\n\n### Arrays\n\n[*Arrays*](https://docs.microsoft.com/dotnet/fsharp/language-reference/arrays) are fixed-size, zero-based, mutable collections of consecutive data elements.\n\n```fsharp\n// Arrays use square brackets with bar\nlet array1 = [| \"a\"; \"b\" |]\n\n// Indexed access using dot\nlet first1 = array1.[0]   \nlet first2 = array1[0]    // F# 6\n```\n      \n### Sequences == IEnumerable\n\n[*Sequences*](https://docs.microsoft.com/dotnet/fsharp/language-reference/sequences) are logical series of elements of the same type. Individual sequence elements are computed only as required, so a sequence can provide better performance than a list in situations in which not all the elements are used.\n\n```fsharp\n// Sequences can use yield and contain subsequences\nseq {\n    // \"yield\" adds one element\n    yield 1\n    yield 2\n\n    // \"yield!\" adds a whole subsequence\n    yield! [5..10]\n}\n```\n\nThe `yield` can normally be omitted:\n\n```fsharp\n// Sequences can use yield and contain subsequences\nseq {\n    1\n    2\n    yield! [5..10]\n}\n```\n\n### Mutable Dictionaries (from BCL)\n\nCreate a dictionary, add two entries, remove an entry, lookup an entry\n\n```fsharp\nopen System.Collections.Generic\n\nlet inventory = Dictionary<string, float>()\n\ninventory.Add(\"Apples\", 0.33)\ninventory.Add(\"Oranges\", 0.5)\n\ninventory.Remove \"Oranges\"\n\n// Read the value. If not exists - throw exception.\nlet bananas1 = inventory.[\"Apples\"]\nlet bananas2 = inventory[\"Apples\"]   // F# 6\n```\n\nAdditional F# syntax:\n\n```fsharp\n// Generic type inference with Dictionary\nlet inventory = Dictionary<_,_>()   // or let inventory = Dictionary()\n\ninventory.Add(\"Apples\", 0.33)\n```\n\n### dict == IDictionary in BCL\n\n*dict* creates immutable dictionaries. You can’t add and remove items to it.\n\n```fsharp\nopen System.Collections.Generic\n\nlet inventory : IDictionary<string, float> =\n    [\"Apples\", 0.33; \"Oranges\", 0.23; \"Bananas\", 0.45]\n    |> dict\n\nlet bananas = inventory.[\"Bananas\"]     // 0.45\nlet bananas2 = inventory[\"Bananas\"]     // 0.45, F# 6\n\ninventory.Add(\"Pineapples\", 0.85)       // System.NotSupportedException\ninventory.Remove(\"Bananas\")             // System.NotSupportedException\n```\n\nQuickly creating full dictionaries:\n\n```\n[ \"Apples\", 10; \"Bananas\", 20; \"Grapes\", 15 ] |> dict |> Dictionary\n```\n\n### Map\n\n*Map* is an immutable key/value lookup. Allows safely add or remove items.\n\n```fsharp\nlet inventory =\n    Map [\"Apples\", 0.33; \"Oranges\", 0.23; \"Bananas\", 0.45]\n\nlet apples = inventory.[\"Apples\"]\nlet apples = inventory[\"Apples\"] // F# 6\nlet pineapples = inventory.[\"Pineapples\"]   // KeyNotFoundException\nlet pineapples = inventory[\"Pineapples\"]    // KeyNotFoundException on F# 6 too\n\nlet newInventory =              // Creates new Map\n    inventory\n    |> Map.add \"Pineapples\" 0.87\n    |> Map.remove \"Apples\"\n```\n\nSafely access a key in a *Map* by using *TryFind*. It returns a wrapped option:\n\n```fsharp\nlet inventory =\n    Map [\"Apples\", 0.33; \"Oranges\", 0.23; \"Bananas\", 0.45]\n\ninventory.TryFind \"Apples\"      // option = Some 0.33\ninventory.TryFind \"Unknown\"     // option = None\n```\n\nUseful Map functions include `map`, `filter`, `partition`:\n\n```fsharp\nlet cheapFruit, expensiveFruit =\n    inventory\n    |> Map.partition(fun fruit cost -> cost < 0.3)\n```\n\n### Dictionaries, dict, or Map?\n\n* Use *Map* as your default lookup type:\n    * It’s immutable\n    * Has good support for F# tuples and pipelining.\n\n* Use the *dict* function\n    * Quickly generate an *IDictionary* to interop with BCL code.\n    * To create a full Dictionary.\n\n* Use *Dictionary*:\n    * If need a mutable dictionary.\n    * Need specific performance requirements. (Example: tight loop performing\n      thousands of additions or removals).\n\n### Generating lists\n\nThe same list `[ 1; 3; 5; 7; 9 ]` can be generated in various ways.\n\n```fsharp\n[ 1; 3; 5; 7; 9 ]\n[ 1..2..9 ]\n[ for i in 0..4 -> 2 * i + 1 ]\nList.init 5 (fun i -> 2 * i + 1)\n```\n\nThe array `[| 1; 3; 5; 7; 9 |]` can be generated similarly:\n\n```fsharp\n[| 1; 3; 5; 7; 9 |]\n[| 1..2..9 |]\n[| for i in 0..4 -> 2 * i + 1 |]\nArray.init 5 (fun i -> 2 * i + 1)\n```\n\n### Functions on collections\n\nLists and arrays have comprehensive functions for manipulation.\n\n  - `List.map` transforms every element of the list (or array)\n  - `List.iter` iterates through a list and produces side effects\n\nThese and other functions are covered below. All these operations are also available for sequences. \n\n<a name=\"Records\"></a>Records\n------------------\n\n*Records* represent simple aggregates of named values, optionally with members:\n\n```fsharp\n// Declare a record type\ntype Person = { Name : string; Age : int }\n\n// Create a value via record expression\nlet paul = { Name = \"Paul\"; Age = 28 }\n\n// 'Copy and update' record expression\nlet paulsTwin = { paul with Name = \"Jim\" }\n```\n\nRecords can be augmented with properties and methods:\n\n```fsharp\ntype Person with\n     member x.Info = (x.Name, x.Age)\n```\n\nRecords are essentially sealed classes with extra topping: default immutability, structural equality, and pattern matching support.\n\n```fsharp\nlet isPaul person =\n    match person with\n    | { Name = \"Paul\" } -> true\n    | _ -> false\n```\n\n<a name=\"Recursive Functions\"></a>Recursion\n----------------\n\nThe `rec` keyword is used together with the `let` keyword to define a recursive function:\n\n```fsharp\nlet rec fact x =\n    if x < 1 then 1\n    else x * fact (x - 1)\n```\n\n*Mutually recursive* functions (those functions which call each other) are indicated by `and` keyword:\n\n```fsharp\nlet rec even x =\n   if x = 0 then true \n   else odd (x - 1)\n\nand odd x =\n   if x = 0 then false\n   else even (x - 1)\n```\n\n`rec` also can be used to define strings like this:\n\n```fsharp\nlet rec name = nameof name\n```\n\n<a name=\"DiscriminatedUnions\"></a>Discriminated Unions\n--------------------\n\n*Discriminated unions* (DU) provide support for values that can be one of a number of named cases, each possibly with different values and types.\n\n```fsharp\ntype Tree<'T> =\n    | Node of Tree<'T> * 'T * Tree<'T>\n    | Leaf\n\n\nlet rec depth input =\n    match input with\n    | Node(l, _, r) -> 1 + max (depth l) (depth r)\n    | Leaf -> 0\n```\n\nF# Core has a few built-in discriminated unions for error handling, e.g., [Option](http://msdn.microsoft.com/en-us/library/dd233245.aspx) and [Result](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/results).\n\nUsing [Option](http://msdn.microsoft.com/en-us/library/dd233245.aspx):\n\n```fsharp\nlet optionPatternMatch input =\n    match input with\n    | Some i -> printfn \"input is an int=%d\" i\n    | None -> printfn \"input is missing\"\n\noptionPatternMatch (Some 1)\noptionPatternMatch None\n```\n\nUsing [Result](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/results):\n\n```fsharp\nlet resultPatternMatch input =\n    match input with\n    | Ok i -> printfn \"Success with code %d\" i\n    | Error e -> printfn \"Error with code %d\" e\n\nresultPatternMatch (Ok 0)\nresultPatternMatch (Error 1)\n```\n\nSingle-case discriminated unions are often used to create type-safe abstractions with pattern matching support:\n\n```fsharp\ntype OrderId = Order of string\n\n// Create a DU value\nlet orderId = Order \"12\"\n\n// Use pattern matching to deconstruct single-case DU\nlet (Order id) = orderId\n```\n\n<a name=\"Exceptions\"></a>Exceptions\n----------\nThe `failwith` function throws an exception of type `Exception`.\n\n```fsharp\nlet divideFailwith x y =\n    if y = 0 then \n        failwith \"Divisor cannot be zero.\" \n        else x / y\n```\n\nException handling is done via `try/with` expressions.\n\n```fsharp\nlet divide x y =\n    try\n        Some (x / y)\n    with :? System.DivideByZeroException -> \n        printfn \"Division by zero!\"\n        None\n```\n  \nThe `try/finally` expression enables you to execute clean-up code even if a block of code throws an exception. Here's an example which also defines custom exceptions.\n\n```fsharp\nexception InnerError of string\nexception OuterError of string\n  \nlet handleErrors x y =\n   try \n       try \n           if x = y then raise (InnerError(\"inner\"))\n           else raise (OuterError(\"outer\"))\n       with InnerError(str) -> \n          printfn \"Error1 %s\" str\n   finally\n       printfn \"Always print this.\"\n```\n\n<a name=\"ClassesAndInheritance\"></a>Classes and Inheritance\n-----------------------\nThis example is a basic class with (1) local let bindings, (2) properties, (3) methods, and (4) static members.\n\n```fsharp\ntype Vector(x: float, y: float) =\n    let mag = sqrt(x * x + y * y)               // (1) - local let binding\n\n    member this.X = x                           // (2) property\n    member this.Y = y                           // (2) property\n    member this.Mag = mag                       // (2) property\n\n    member this.Scale(s) =                       // (3) method\n        Vector(x * s, y * s)\n\n    static member (+) (a : Vector, b : Vector) = // (4) static method\n        Vector(a.X + b.X, a.Y + b.Y)\n```\n\nCall a base class from a derived one:\n\n```fsharp\ntype Animal() =\n    member _.Rest() = ()\n           \ntype Dog() =\n    inherit Animal()\n    member _.Run() =\n        base.Rest()\n```\n\n<a name=\"InterfacesAndObjectExpressions\"></a>Interfaces and Object Expressions\n---------------------------------\nDeclare `IVector` interface and implement it in `Vector'`.\n\n```fsharp\ntype IVector =\n    abstract Scale : float -> IVector\n\ntype Vector(x, y) =\n    interface IVector with\n        member __.Scale(s) =\n            Vector(x * s, y * s) :> IVector\n            \n    member __.X = x\n    \n    member __.Y = y\n```\n\nAnother way of implementing interfaces is to use *object expressions*.\n\n```fsharp\ntype ICustomer =\n    abstract Name : string\n    abstract Age : int\n\nlet createCustomer name age =\n    { new ICustomer with\n        member __.Name = name\n        member __.Age = age }\n```\n\n<a name=\"CastingAndConversions\"></a>Casting and Conversions\n---------------\n\n```fsharp\nint 3.1415     // float to int = 3\nint \"3\"        // string to int = 3\nfloat 3        // int to float = 3.0\nfloat \"3.1415\" // string to float = 3.1415\nstring 3       // int to string = \"3\"\nstring 3.1415  // float to string = \"3.1415\"\n```\n\n*Upcasting* is denoted by `:>` operator.\n\n```fsharp\nlet dog = Dog() \nlet animal = dog :> Animal\n```\n\nIn many places type inference applies upcasting automatically:\n\n```fsharp\nlet exerciseAnimal (animal: Animal) = () \n\nlet dog = Dog()\n\nexerciseAnimal dog   // no need to upcast dog to Animal\n```\n\n*Dynamic downcasting* (`:?>`) might throw an `InvalidCastException` if the cast doesn't succeed at runtime.\n\n```fsharp\nlet shouldBeADog = animal :?> Dog\n```\n\n<a name=\"ActivePatterns\"></a>Active Patterns\n---------------\n\n*Complete active patterns*:\n\n```fsharp\nlet (|Even|Odd|) i = \n  if i % 2 = 0 then Even else Odd\n\nlet testNumber i =\n    match i with\n    | Even -> printfn \"%d is even\" i\n    | Odd -> printfn \"%d is odd\" i\n```\n\n*Parameterized, partial active patterns*:\n\n```fsharp\nlet (|DivisibleBy|_|) divisor n = \n  if n % divisor = 0 then Some DivisibleBy else None\n\nlet fizzBuzz input =\n    match input with\n    | DivisibleBy 3 & DivisibleBy 5 -> \"FizzBuzz\" \n    | DivisibleBy 3 -> \"Fizz\" \n    | DivisibleBy 5 -> \"Buzz\" \n    | i -> string i\n```\n\n*Partial active patterns* share the syntax of parameterized patterns but their active recognizers accept only one argument.\n\n<a name=\"CompilerDirectives\"></a>Compiler Directives\n-------------------\n\nLoad another F# source file into F# Interactive (`dotnet fsi`).\n\n```fsharp\n#load \"../lib/StringParsing.fs\"\n```\n\nReference a .NET package:\n\n```fsharp\n#r \"nuget: FSharp.Data\"                // latest non-beta version\n#r \"nuget: FSharp.Data,Version=4.2.2\"  // specific version\n```\n\nSpecifying a package source:\n\n```fsharp\n#i \"nuget: https://my-remote-package-source/index.json\"\n\n#i \"\"\"nuget: C:\\path\\to\\my\\local\\source\"\"\"\n```\n\nReference a specific .NET assembly file:\n\n```fsharp\n#r \"../lib/FSharp.Markdown.dll\"\n```\n\nInclude a directory in assembly search paths:\n\n```fsharp\n#I \"../lib\"\n#r \"FSharp.Markdown.dll\"\n```\n\nOther important directives are conditional execution in FSI (`INTERACTIVE`), conditional for compiled code (`COMPILED`) and querying current directory (`__SOURCE_DIRECTORY__`).\n\n```fsharp\n#if INTERACTIVE\nlet path = __SOURCE_DIRECTORY__ + \"../lib\"\n#else\nlet path = \"../../../lib\"\n#endif\n```\n\n<a name=\"Acknowledgments\"></a>Acknowledgments\n--------\n\nThanks goes to these people/projects:\n\n- [dungpa/fsharp-cheatsheet](https://github.com/dungpa/fsharp-cheatsheet)\n- [artag/fsharp-cheatsheet](https://github.com/artag/fsharp-cheatsheet)\n- [thriuin/fsharp-cheatsheet](https://github.com/thriuin/fsharp-cheatsheet)\n- [Succinct FSharp](https://dasdocs.com/fsharp/1-succinct-fsharp.html)\n\n"
  },
  {
    "path": "fsharp_vs_csharp.md",
    "content": "# F# vs C# Cheat Sheet\n\n## Classes with properties and default constructor\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Vector(x : float, y : float) =\n    member this.X = x\n    member this.Y = y\n \n// Usage:\nlet v = Vector(10., 10.)\nlet x = v.X\nlet y = v.Y\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Vector\n{\n    private double x;\n    private double y;\n \n    public Vector(double x, double y)\n    {\n        this.x = x;\n        this.y = y;\n    }\n\n    public double X\n    {\n        get =>  { return this.x; }\n    }\n    public double Y\n    {\n        get { return this.y; }\n    }\n}\n \n// Usage:\nvar v = new Vector(10, 10);\nvar x = v.X;\nvar y = v.Y;\n```\n\n</td></tr></table>\n\n## Structs with properties\n\n<table><tr><td valign=\"top\">\n\n```fsharp\n[<Struct>]\ntype Vector(x : float, y : float) =\n    member this.X = x\n    member this.Y = y\n \n// Usage:\nlet v = Vector(10., 10.)\nlet x = v.X\nlet y = v.Y\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic struct Vector\n{\n    double x;\n    double y;\n \n    public Vector(double x, double y)\n    {\n        this.x = x;\n        this.y = y;\n    }\n    public double X\n    {\n        get { return this.x; }\n    }\n    public double Y\n    {\n        get { return this.y; }\n    }\n}\n \n// Usage:\nVector v = new Vector(10, 10);\ndouble x = v.X;\ndouble y = v.Y;\n```\n\n</td></tr></table>\n\n## Multiple constructors\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Vector(x : float, y : float) =\n    member this.X = x\n    member this.Y = y\n    new(v : Vector, s) = Vector(v.X * s, v.Y * s)\n \n// Usage:\nlet v = Vector(10., 10.)\nlet w = Vector(v, 0.5)\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Vector\n{\n    double x;\n    double y;\n    public Vector(double x, double y)\n    {\n        this.x = x;\n        this.y = y;\n    }\n    public Vector(Vector v, double s) :\n        this(v.x * s, v.y * s)\n    {\n    }\n}\n \n// Usage:\nVector v = new Vector(10, 10);\nVector w = new Vector(v, 0.5);\n```\n\n</td></tr></table>\n\n## Member functions\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Vector(x : float, y : float) =\n    member this.Scale(s : float) =\n        Vector(x * s, y * s)\n \n// Usage:\nlet v = Vector(10., 10.)\nlet v2 = v.Scale(0.5)\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Vector\n{\n    double x;\n    double y;\n \n    public Vector(double x, double y)\n    {\n        this.x = x;\n        this.y = y;\n    }\n    public double Scale(double s)\n    {\n        return new Vector(this.x * s,\n            this.y * s);\n    }\n}\n \n// Usage:\nVector v = new Vector(10, 10);\nVector v2 = v.Scale(0.5);\n```\n\n</td></tr></table>\n\n## Operators\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Vector(x, y) =\n    member this.X = x\n    member this.Y = y\n    static member (*) (a : Vector, b : Vector) =\n        a.X * b.X + a.Y + b.Y\n \n// Usage:\nlet x = Vector(2., 2.)\nlet y = Vector(3., 3.)\nlet dp = x * y\n\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Vector\n{\n    double x;\n    double y;\n    public Vector(double x, double y)\n    {\n        this.x = x;\n        this.y = y;\n    }\n    public double X\n    {\n        get { return this.x; }\n    }\n    public double Y\n    {\n        get { return this.y; }\n    }\n    public static double operator * (\n        Vector v1, Vector v2)\n    {\n        return v1.x * v2.x + v1.y * v2.y;\n    }\n}\n \n// Usage:\nVector x = new Vector(2, 2);\nVector y = new Vector(3, 3);\ndouble dp = x * y;\n```\n\n</td></tr></table>\n\n## Static members and properties\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Vector(x, y) =\n    member this.X = x\n    member this.Y = y\n    static member Dot(a : Vector, b : Vector) =\n        a.X * b.X + a.Y + b.Y\n    static member NormX = Vector(1., 0.)\n \n// Usage:\nlet x = Vector(2., 2.)\nlet y = Vector.NormX\nlet dp = Vector.Dot(x, y)\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Vector\n{\n    double x;\n    double y;\n    public Vector(double x, double y)\n    {\n        this.x = x;\n        this.y = y;\n    }\n    public double X\n    {\n        get { return this.x; }\n    }\n    public double Y\n    {\n        get { return this.y; }\n    }\n    public static double Dot(Vector v1,\n        Vector v2)\n    {\n        return v1.x * v2.x + v1.y * v2.y;\n    }\n    public static Vector NormX\n    {\n        get { return new Vector(1, 0); }\n    }\n}\n \n// Usage:\nVector x = new Vector(2, 2);\nVector y = Vector.NormX;\ndouble dp = Vector.Dot(x, y);\n```\n\n</td></tr></table>\n\n## Class properties that use let value computations in the constructor\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Vector(x, y) =\n    let mag = sqrt(x * x + y * y)\n    let rad = if x = 0. && y = 0. then\n                  0.\n              else if x >= 0. then\n                  asin(y / mag)\n              else\n                  (-1. * asin(y / mag)) +\n                      Math.PI\n    member this.Mag = mag\n    member this.Rad = rad\n \n// Usage:\nlet v = Vector(10., 10.)\nlet mag = v.Mag\nlet rad = v.Rad\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Vector\n{\n    double mag = 0.0;\n    double rad = 0.0;\n    public Vector(double x, double y)\n    {\n        this.mag = Math.Sqrt(x * x + y * y);\n        if (x == 0.0 && y == 0.0) rad = 0.0;\n        else if (x >= 0.0)\n            rad = Math.Asin(y / mag);\n        else\n            rad = (-1.0 * Math.Asin(y / mag)) + Math.PI;\n    }\n    public double Mag\n    {\n        get { return this.mag; }\n    }\n    public double Rad\n    {\n        get { return this.rad; }\n    }\n}\n \n// Usage:\nVector v = new Vector(10, 10);\ndouble mag = v.Mag;\ndouble rad = v.Rad;\n```\n\n</td></tr></table>\n\n## Class members that use private function values\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Vector(x, y) =\n    let rotate a =\n        let x' = x * cos a – y * sin a\n        let y' = y * sin a + y * cos a\n        new Vector(x', y')\n    member this.RotateByDegrees(d) =\n        rotate (d * Math.PI / 180.)\n    member this.RotateByRadians(r) =\n        rotate r\n \n// Usage:\nlet v = Vector(10., 0.)\nlet x = v.RotateByDegrees(90.)\nlet y = v.RotateByRadians(Math.PI / 6.)\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Vector\n{\n    double x = 0.0;\n    double y = 0.0;\n    Vector rotate(double a)\n    {\n        double xx = this.x * Math.Cos(a) –\n                    this.y * Math.Sin(a);\n        double yy = this.y * Math.Sin(a) +\n                    this.y * Math.Cos(a);\n        return new Vector(xx, yy);\n    }\n    public Vector(double x, double y)\n    {\n        this.x = x;\n        this.y = y;\n    }\n    public Vector RotateByDegrees(double d)\n    {\n        return rotate(d * Math.PI / 180);\n    }\n    public Vector RotateByRadians(double r)\n    {\n        return rotate(r);\n    }\n}\n \n// Usage:\nVector v = new Vector(10, 10);\nVector x = v.RotateByDegrees(90.0);\nVector y = v.RotateByRadians(Math.PI / 6.0);\n```\n\n</td></tr></table>\n\n\n## Overloading members\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Car() =\n    member this.Drive() =\n        this.Drive(10)\n        ()\n    member this.Drive(mph : int) =\n        // Do something\n        ()\n \n// Usage:\nlet c = Car()\nc.Drive()\nc.Drive(10)\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Car\n{\n    public void Drive()\n    {\n        Drive(10);\n    }\n    public void Drive(int mph)\n    {\n        // Do something\n    }\n}\n \n// Usage:\nCar c = new Car();\nc.Drive();\nc.Drive(10);\n```\n\n</td></tr></table>\n\n## Mutable fields in a class with get/set properties\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype MutableVector(x : float, y : float) =\n    let mutable cx = x\n    let mutable cy = y\n    member this.X with get() = cx and\n                       set(v) = cx <- v\n    member this.Y with get() = cy and\n                       set(v) = cy <- v\n    member this.Length = sqrt(x * x + y * y)\n \n// Usage:\nlet v = MutableVector(2., 2.)\nlet len1 = v.Length\nv.X <- 3.\nv.Y <- 3.\nlet len2 = v.Length\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class MutableVector\n{\n    public MutableVector(double x, double y)\n    {\n        this.X = x;\n        this.Y = y;\n    }\n    public double X { get; set; }\n    public double Y { get; set; }\n    public double Length\n    {\n        get { return Math.Sqrt(\n                  this.X * this.X +\n                  this.Y * this.Y); }\n    }\n}\n \n// Usage:\nMutableVector v = new MutableVector(2.0, 2.0);\ndouble len1 = v.Length;\nv.X = 3.0;\nv.Y = 3.0;\ndouble len2 = v.Length;\n```\n\n</td></tr></table>\n\n## Generic classes and function arguments\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Factory<'T>(f : unit -> 'T) =\n    member this.Create() =\n        f()\n \n// Usage:\nlet strings = Factory<string>(\n    fun () -> \"Hello!\")\nlet res = strings.Create()\nlet ints = Factory<int>(fun () -> 10)\nlet res = ints.Create()\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Factory<T>\n{\n    Func<T> creator;\n    public Factory(Func<T> f)\n    {\n        this.creator = f;\n    }\n    public T Create()\n    {\n        return this.creator();\n    }\n}\n \n// Usage:\nvar strings = new\n    Factory<string>(() => \"Hello\");\nvar res1 = strings.Create();\nvar ints = new Factory<int>(() => 10);\nvar res2 = ints.Create();\n```\n\n</td></tr></table>\n\n## Generic classes and methods\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Container<'T>(a : 'T) =\n    member this.Convert<'U>(f : 'T -> 'U) =\n        f a\n \n// Usage:\nlet c = new Container<int>(10)\nlet b = c.Convert(fun a -> a.ToString())\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Container<T>\n{\n    private T value;\n    public Container(T t)\n    {\n        this.value = t;\n    }\n    public U Convert<U>(Func<T, U> f)\n    {\n        return f(this.value);\n    }\n}\n \n// Usage:\nContainer<int> c = new Container<int>(10);\nstring result = c.Convert(n => n.ToString());\n```\n\n</td></tr></table>\n\n## Extension methods\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype List<'T> with\n    member this.MyExtensionMethod() =\n        this |> Seq.map (fun a -> a.ToString())\n \n// Usage:\nlet c = [1; 2; 3]\nlet d = c.MyExtensionMethod()\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic static class ExtensionMethods\n{\n    public static IEnumerable<string>\n        MyExtensionMethod<T>(this List<T> a)\n    {\n        return a.Select(s => s.ToString());\n    }\n}\n \n// Usage:\nList<int> l = new List<int> { 1, 2, 3 };\nIEnumerable<string> res =\n    l.MyExtensionMethod();\n```\n\n</td></tr></table>\n\n## Extension properties\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype List<'T> with\n    member this.MyExtensionProp =\n        this |> Seq.map (fun a -> a.ToString())\n \n// Usage:\nlet c = [1; 2; 3]\nlet d = c.MyExtensionProp\n```\n\n</td><td valign=\"top\">\n\n```csharp\n// N/A. C# does not support this feature.\n```\n\n</td></tr></table>\n\n\n## Indexers\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Table() =\n    member this.Item\n        with get(key : string) = int key\n \n// Usage:\nlet tab = Table()\nlet x = tab.[\"10\"]\nlet y = tab.[\"12\"]\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Table\n{\n    public int this[string key]\n    {\n        get { return Convert.ToInt32(key); }\n    }\n}\n \n// Usage:\nTable tab = new Table();\nint x = tab[\"10\"];\nint y = tab[\"12\"];\n```\n\n</td></tr></table>\n\n## Indexed Properties\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Table() =\n    member this.Values\n        with get(key : string) = int key\n    member this.MultipleValues\n        with get(key1, key2) = key1 + key2\n// Usage:\nlet tab = Table()\nlet x = tab.Values(\"10\")\nlet y = tab.Values(\"12\")\nlet a = tab.MultipleValues(10, 5)\n```\n\n</td><td valign=\"top\">\n\n```csharp\n// N/A. C# does not support this feature.\n```\n\n</td></tr></table>\n\n## Abstract classes\n\n<table><tr><td valign=\"top\">\n\n```fsharp\n[<AbstractClass>]\ntype Shape() =\n    abstract Name : string with get\n    abstract Scale : float -> Shape\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic abstract class Shape\n{\n    public abstract string Name { get; }\n    public abstract Shape Scale(double scale);\n}\n```\n\n</td></tr></table>\n\n\n## Derive from a base class and overriding base methods with generics\n\n<table><tr><td valign=\"top\">\n\n```fsharp\n[<AbstractClass>]\ntype Shape<'T>() =\n    abstract Name : string with get\n    abstract Scale : float -> 'T\n   \ntype Vector(angle, mag) =\n    inherit Shape<Vector>()\n    member this.Angle = angle\n    member this.Mag = makg\n    override this.Name = \"Vector\"\n    override this.Scale(factor) =\n        Vector(angle, mag * factor)\n \n// Usage:\nlet v = Vector(45., 10.)\nlet v2 = v.Scale(0.5)\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic abstract class Shape<T>\n{\n    public abstract string Name { get; }\n    public abstract T Scale(double scale);\n}\n \npublic class Vector : Shape<Vector>\n{\n    double angle;\n    double mag;\n    public double Angle {get{return angle;}}\n    public double Mag {get{return mag;}}\n    public Vector(double angle, double mag)\n    {\n        this.angle = angle;\n        this.mag = mag;\n    }\n    public override string Name\n    {\n        get { return \"Vector\"; }\n    }\n    public override Vector Scale(double scale)\n    {\n        return new Vector(this.Angle,\n            this.Mag * scale);\n    }\n}\n// Usage:\nVector v = new Vector(45, 10);\nVector v2 = v.Scale(0.5);\n```\n\n</td></tr></table>\n\n## Calling a base class method\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Animal() =\n    member this.Rest() =\n        // Rest for the animal\n        ()\n           \ntype Dog() =\n    inherit Animal()\n    member this.Run() =\n        // Run\n        base.Rest()\n// Usage:\nlet brian = new Dog()\nbrian.Run()\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Animal\n{\n    public void Rest()\n    {\n        // Rest for the animal\n    }\n}\npublic class Dog : Animal\n{\n    public void Run()\n    {\n        // Run\n        base.Rest();\n    }\n}\n// Usage:\nDog brian = new Dog();\nbrian.Run();\n```\n\n</td></tr></table>\n\n## Implementing an interface\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype IVector =\n    abstract Mag : double with get\n    abstract Scale : float -> IVector\n       \ntype Vector(x, y) =\n    interface IVector with\n        member this.Mag = sqrt(x * x + y * y)\n        member this.Scale(s) =\n            Vector(x * s, y * s) :> IVector\n    member this.X = x\n    member this.Y = y\n// Usage:\nlet v = new Vector(1., 2.) :> IVector\nlet w = v.Scale(0.5)\nlet mag = w.Mag\n```\n\n</td><td valign=\"top\">\n\n```csharp\ninterface IVector\n{\n    double Mag { get; }\n    IVector Scale(double s);\n}\nclass Vector : IVector\n{\n    double x;\n    double y;\n    public Vector(double x, double y)\n    {\n        this.x = x;\n        this.y = y;\n    }\n    public double X\n    {\n        get { return this.x; }\n    }\n    public double Y\n    {\n        get { return this.y; }\n    }\n    public double Mag\n    {\n        get { return Math.Sqrt( this.x * this.x +\n                this.y * this.y); }\n    }\n    public IVector Scale(double s)\n    {\n        return new Vector(this.x * s,\n            this.y * s);\n    }\n}\n// Usage:\nIVector v = new Vector(1, 2);\nIVector w = v.Scale(0.5);\ndouble mag = w.Mag;\n```\n\n</td></tr></table>\n\n## Implementing an interface with object expressions\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype ICustomer =\n    abstract Name : string with get\n    abstract Age : int with get\n       \nlet CreateCustomer name age =\n    { new ICustomer with\n        member this.Name = name\n        member this.Age = age\n    }\n// Usage:\nlet c = CreateCustomer \"Snoopy\" 16\nlet d = CreateCustomer \"Garfield\" 5\n```\n\n</td><td valign=\"top\">\n\n```csharp\n/// N/A. C# does not support creating object expressions.\n```\n\n</td></tr></table>\n\n## Events\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype BarkArgs(msg:string) =\n    inherit EventArgs()\n    member this.Message = msg\n \ntype BarkDelegate =\n    delegate of obj * BarkArgs -> unit\n \ntype Dog() =\n    let ev = new Event<BarkDelegate, BarkArgs>()\n    member this.Bark(msg) =\n        ev.Trigger(this, new BarkArgs(msg))\n    [<CLIEvent>]\n    member this.OnBark = ev.Publish\n// Usage:\nlet snoopy = new Dog()\nsnoopy.OnBark.Add(\n    fun ba -> printfn \"%s\" (ba.Message))\nsnoopy.Bark(\"Hello\")\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class BarkArgs : EventArgs\n{\n    private string msg;\n    public BarkArgs(string msg)\n    {\n        this.msg = msg;\n    }\n    public string Message\n    {\n        get { return this.msg; }\n    }\n}\n \npublic delegate void BarkDelegate(\n    Object sender, BarkArgs args);\n \nclass Dog\n{\n    public event BarkDelegate OnBark;\n    public void Bark(string msg)\n    {\n        OnBark(this, new BarkArgs(msg));\n    }\n}\n// Usage:\nDog snoopy = new Dog();\nsnoopy.OnBark += new BarkDelegate(\n    (sender, msg) =>\n        Console.WriteLine(msg.Message));\nsnoopy.Bark(\"Hello\");\n```\n\n</td></tr></table>\n\n## Explicit class constructor\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Vector =\n    val mutable x : float\n    val mutable y : float\n    new() = {x = 0.; y = 0.}\n       \n// Usage:\nlet v = Vector()\nv.x <- 10.\nv.y <- 10.\n```\n\n</td></tr></table>\n\n\n## Explicit public fields\n\n<table><tr><td valign=\"top\">\n\n```fsharp\ntype Vector() =\n    [<DefaultValue()>]\n    val mutable x : int\n    [<DefaultValue()>]\n    val mutable y : int\n \n// Usage:\nlet v = Vector()\nv.x <- 10\nv.y <- 10\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic class Vector\n{\n    public int x;\n    public int y;\n}\n \n// Usage:\nVector v = new Vector();\nv.x = 10;\nv.y = 10;\n```\n\n</td></tr></table>\n\n## Explicit struct definition\n\n<table><tr><td valign=\"top\">\n\n```fsharp\n[<Struct>]\ntype Vector =\n    val mutable public x : int\n    val mutable public y : int\n \n// Usage:\nlet mutable v = Vector()\nv.x <- 10\nv.y <- 10\n```\n\n</td><td valign=\"top\">\n\n```csharp\npublic struct Vector\n{\n    public int x;\n    public int y;\n}\n \n// Usage:\nVector v = new Vector();\nv.x = 10;\nv.y = 10;\n```\n\n</td></tr></table>\n\n## Links\n    \n- [Original source](https://docs.microsoft.com/en-gb/archive/blogs/timng/f-quick-guides-object-oriented-programming)\n- [Converting between F# and C# types](https://devonburriss.me/converting-fsharp-csharp/)    \n    \n"
  },
  {
    "path": "functions.md",
    "content": "<a name=\"UsefulFunctions\"></a>Useful functions\n-------------------\n\n#### [identity function (id)](https://fsharp.github.io/fsharp-core-docs/reference/fsharp-core-operators.html#id)\n\nIt's useful for cases where you need a lambda like `fun x -> x`:\n\n```fsharp\n[[1;2]; [3]] |> List.collect (fun x -> x)  // [1; 2; 3]\n[[1;2]; [3]] |> List.collect id            // [1; 2; 3]\n```\n\n<a name=\"MappingFunctions\"></a>Mapping functions\n-------------------\n\n#### map (Array, List, Seq)\n\nConverts all the items in a collection from one shape to another shape.\nAlways returns the same number of items in the output collection as were passed in.\n\n```fsharp\n// [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]\n[1 .. 10] |> List.map (fun n -> n * 2)\n\ntype Person = { Name : string; Town : string }\n\nlet persons =\n    [\n        { Name = \"Isaak\"; Town = \"London\" }\n        { Name = \"Sara\"; Town = \"Birmingham\" }\n        { Name = \"Tim\"; Town = \"London\" }\n        { Name = \"Michelle\"; Town = \"Manchester\" }\n    ]\n\n// [\"London\"; \"Birmingham\"; \"London\"; \"Manchester\"]\npersons |> List.map (fun person -> person.Town)\n```\n\n#### map2, map3 (Array, List, Seq)\n\n*map2* and *map3* are variations of *map* that take multiple lists.\n The collections must have equal lengths, except for `Seq.map2` and `Seq.map3` where extra elements are ignored.\n \n```fsharp\nlet list1 = [1; 2; 3]\nlet list2 = [4; 5; 6]\nlet list3 = [7; 8; 9]\n\n// [5; 7; 9]\n(list1, list2) ||> List.map2 (fun x y -> x + y)\n\n// [12; 15; 18]\n(list1, list2, list3) |||> List.map3 (fun x y z -> x + y + z) \n```\n\n#### mapi, mapi2 (Array, List, Seq)\n\n*mapi* and *mapi2* - in addition to the element, the function needs to be\npassed the index of each element. The only difference `mapi2` and `mapi` is that `mapi2` works\nwith two collections.\n\n```fsharp\nlet list1 = [9; 12; 53; 24; 35]\n\n// [(0, 9); (1, 12); (2, 53); (3, 24); (4, 35)]\nlist1 |> List.mapi (fun x i -> (x, i))\n\n// [9; 13; 55; 27; 39]\nlist1 |> List.mapi (fun x i -> x + i)\n\nlet list1 = [9; 12; 3]\nlet list2 = [24; 5; 2]\n\n// [0; 17; 10]\n(list1, list2) ||> List.mapi2 (fun i x y -> (x + y) * i) \n```\n\n### indexed (Array, List, Seq)\n\nReturns a new collection whose elements are the corresponding elements of the input\npaired with the index (from 0) of each element.\n\n```fsharp\nlet list1 = [23; 5; 12]\n\n// [(0, 23); (1, 5); (2, 12)]\nlet result = list1 |> Array.indexed\n```\n\n### iter, iter2, iteri, iteri2 (Array, List, Seq)\n\n*iter* is the same as a `for` loop, the function that you pass in must return unit.\n\n```fsharp\nlet list1 = [1; 2; 3]\nlet list2 = [4; 5; 6]\n\n// Prints: 1; 2; 3; \nlist1 |> List.iter (fun x -> printf \"%d; \" x)\n\n// Prints: (1 4); (2 5); (3 6);\n(list1, list2) ||> List.iter2 (fun x y -> printf \"(%d %d); \" x y)\n\n// Prints: ([0] = 1); ([1] = 2); ([2] = 3);\nlist1 |> List.iteri (fun i x -> printf \"([%d] = %d); \" i x)\n\n// Prints: ([0] = 1 4); ([1] = 2 5); ([2] = 3 6);\n(list1, list2) ||> List.iteri2 (fun i x y -> printf \"([%d] = %d %d); \" i x y) \n```\n\n### collect (Array, List, Seq)\n\n*collect* runs a specified function on each element and then collects the elements\ngenerated by the function and combines them into a new collection.\n\n```fsharp\n// [0; 1; 0; 1; 2; 3; 4; 5; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10]\nlet list1 = [1; 5; 10]\nlet list2 = [1; 2; 3]\n\nlist1 |> List.collect (fun elem -> [0 .. elem])\n\n// [1; 2; 3; 2; 4; 6; 3; 6; 9]\nlist2 |> List.collect (fun x -> [for i in 1..3 -> x * i])\n\n// Example 3\ntype Customer =\n    {\n        Id: int\n        OrderId: int list\n    }\n\nlet c1 = { Id = 1; OrderId = [1; 2]}\nlet c2 = { Id = 2; OrderId = [43]}\nlet c3 = { Id = 5; OrderId = [39; 56]}\nlet customers = [c1; c2; c3]\n\n// [1; 2; 43; 39; 56]\nlet orders = customers |> List.collect(fun c -> c.OrderId)\n```\n\n### pairwise (Array, List, Seq)\n\n*pairwise* takes a collection and returns a new list of tuple pairs of\nthe original adjacent items.\n\n```fsharp\nlet list1 = [1; 30; 12; 20]\n\n//  [(1, 30); (30, 12); (12, 20)]\nlist1 |> List.pairwise\n\n// [31.0; 11.0; 21.0]\n[ DateTime(2010,5,1)\n  DateTime(2010,6,1)\n  DateTime(2010,6,12)\n  DateTime(2010,7,3) ]\n|> List.pairwise\n|> List.map(fun (a, b) -> b - a)\n|> List.map(fun time -> time.TotalDays)\n```\n\n### windowed (Array, List, Seq)\n\nReturns a list of sliding windows containing elements drawn from the input\ncollection. Each window is returned as a fresh collection. Unlike *pairwise* \nthe windows are collections, not tuples.\n\n```fsharp\n// [['a'; 'b'; 'c']; ['b'; 'c'; 'd']; ['c'; 'd'; 'e']]\n['a'..'e'] |> List.windowed 3\n```\n\n<a name=\"GroupingFunctions\"></a>Grouping functions\n-------------------\n\n### groupBy (Array, List, Seq) == GroupBy() in LINQ\n\n*groupBy* works exactly as the LINQ version does. The output is a collection of simple tuples.\nThe first element of the tuple is the key, and the second element is the collection of items\nin that group.\n\n```fsharp\ntype Person =\n    {\n        Name: string\n        Town: string\n    }\n\nlet persons =\n    [ { Name = \"Isaak\"; Town = \"London\" }\n      { Name = \"Sara\"; Town = \"Birnmingham\" }\n      { Name = \"Tim\"; Town = \"London\" }\n      { Name = \"Michelle\"; Town = \"Manchester\" } ]\n\n// [(\"London\", [{ Name = \"Isaak\"; Town = \"London\" }; { Name = \"Tim\"; Town = \"London\" }]);\n//  (\"Birnmingham\", [{ Name = \"Sara\"; Town = \"Birnmingham\" }]);\n//  (\"Manchester\", [{ Name = \"Michelle\"; Town = \"Manchester\" }])]\npersons |> List.groupBy (fun person -> person.Town)\n```\n\n### countBy (Array, List, Seq)\n\nA useful derivative of *groupBy* is *countBy*. This has a similar signature, but instead of\nreturning the items in the group, it returns the number of items in each group.\n\n```fsharp\ntype Person = { Name: string; Town: string }\n\nlet persons =\n    [\n        { Name = \"Isaak\"; Town = \"London\" }\n        { Name = \"Sara\"; Town = \"Birnmingham\" }\n        { Name = \"Tim\"; Town = \"London\" }\n        { Name = \"Michelle\"; Town = \"Manchester\" }\n    ]\n\n// [(\"London\", 2); (\"Birnmingham\", 1); (\"Manchester\", 1)]\npersons |> List.countBy (fun person -> person.Town)\n```\n\n### partition (Array, List)\n\n*partition* use predicate and a collection; it returns two collections,\npartitioned based on the predicate:\n\n```fsharp\n// Tupled result in two lists\nlet londonPersons, otherPersons =\n    persons |> List.partition(fun p -> p.Town = \"London\")\n```\n\nIf there are no matches for either half of the split, an empty collection is\nreturned for that half.\n\n### chunkBySize (Array, List, Seq)\n\n*chunkBySize* groups elements into arrays (chunks) of a given size.\n\n```fsharp\nlet list1 = [33; 5; 16]\n\n// int list list = [[33; 5]; [16]]\nlet chunkedLst = list1 |> List.chunkBySize 2\n```\n\n### splitAt (Array, List)\n\n*splitAt* splits an Array (List) into two parts at the index you specify.\nThe first part ends just before the element at the given index;\nthe second part starts with the element at the given index.\n\n```fsharp\nlet xs = [| 1; 2; 3; 4; 5 |]\n\nlet left1, right1 = xs |> Array.splitAt 0   // [||] and [|1; 2; 3; 4; 5|]\nlet left2, right2 = xs |> Array.splitAt 1   // [|1|] and [|2; 3; 4; 5|]\nlet left3, right3 = xs |> Array.splitAt 5   // [|1; 2; 3; 4; 5|] and [||]\nlet left4, right4 = xs |> Array.splitAt 6   // InvalidOperationException\n```\n\n### splitInto (Array, List, Seq)\n\nSplits the input collection into at most count chunks.\n\n```fsharp\n// [[1; 2; 3; 4]; [5; 6; 7]; [8; 9; 10]]\n// note that the first chunk has four elements\n[1..10] |> List.splitInto 3\n\n// [[1; 2; 3]; [4; 5; 6]; [7; 8]; [9; 10]]\n[1..10] |> List.splitInto 4\n\n// [[1; 2]; [3; 4]; [5; 6]; [7; 8]; [9]; [10]]\n[1..10] |> List.splitInto 6\n```\n\n## Aggregate functions\n\nAggregate functions take a collection of items and merge them into a smaller\ncollection of items (often just one).\n\n### sum, average, min, max (Array, List, Seq)\n\nAll of these functions are specialized versions of a more generalized function *fold*.\n\n```fsharp\nlet numbers = [1.0 .. 10.0]\n\nlet total = numbers |> List.sum         // 55.0\nlet average = numbers |> List.average   // 5.5\nlet max = numbers |> List.max           // 10.0\nlet min = numbers |> List.min           // 1.0\n```\n\n##  Miscellaneous functions\n\n### find (Array, List, Seq) == Single() in LINQ\n\n*find* - finds the first element that matches a given condition.\n\n```fsharp\nlet isDivisibleBy number elem = elem % number = 0\n\nlet input = [1 .. 10]\n\ninput |> List.find (isDivisibleBy 5)    // 5\ninput |> List.find (isDivisibleBy 11)   // KeyNotFoundException\n```\n\n### findBack (Array, List, Seq) \n\n```fsharp\nlet isDivisibleBy number elem = elem % number = 0\n\nlet input = [1 .. 10]\n\ninput |> List.findBack (isDivisibleBy 4)    // 8\ninput |> List.findBack (isDivisibleBy 11)   // KeyNotFoundException\n```\n\n### findIndex (Array, List, Seq)\n\n```fsharp\nlet isDivisibleBy number elem = elem % number = 0\n\nlet input = [1 .. 10]\n\ninput |> List.findIndex (isDivisibleBy 5)   // 4\ninput |> List.findIndex (isDivisibleBy 11)  // KeyNotFoundException\n```\n\n### findIndexBack (Array, List, Seq)\n\n```fsharp\nlet isDivisibleBy number elem = elem % number = 0\n\nlet input = [1..10]\n\ninput |> List.findIndexBack (isDivisibleBy 3)   // 8\ninput |> List.findIndexBack (isDivisibleBy 11)  // KeyNotFoundException\n```\n\n### head, last, tail, item (Array, List, Seq)\n\nReturns the first, last and all-but-first items in the collection.\n\n```fsharp\nlet input = [15..22]\n\ninput |> List.head    // 15\ninput |> List.last    // 22\ninput |> List.tail    // [16; 17; 18; 19; 20; 21; 22]\n```\n\n### item (Array, List, Seq)\n\nGets the element at a given index.\n\n```fsharp\nlet input = [1..7]\n\ninput |> List.item 5      // 6\ninput |> List.item 8      // ArgumentException\n```\n\n### take (Array, List, Seq)\n\nReturns the elements of the collection up to a specified count.\n\n```fsharp\nlet input = [1..10]\n\ninput |> List.take 5        // [1; 2; 3; 4; 5]\ninput |> List.take 11       // InvalidOperationException\n```\n\n### truncate (Array, List, Seq)\n\nReturns a collection that when enumerated returns at most N elements.\n\n```fsharp\nlet input = [1..10]\n\ninput |> List.truncate 5    // [1; 2; 3; 4; 5]\ninput |> List.truncate 11   // [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]\n```\n\n### takeWhile (Array, List, Seq)\n\n*takeWhile* returns each item in a new collection until it reaches an item that\ndoes not meet the predicate.\n\n```fsharp\nlet input = [1..10]\n\ninput |> List.takeWhile (fun x -> x / 7 = 0)   // [1; 2; 3; 4; 5; 6]\ninput |> List.takeWhile (fun x -> x / 17 = 0)     // [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]\n```\n\n### skip (Array, List, Seq)\n\nReturns a collection that skips N elements of the underlying sequence and then yields\nthe remaining elements.\n\n```fsharp\nlet input = [ for i in 1 .. 10 -> i * i ]  // [1; 4; 9; 16; 25; 36; 49; 64; 81; 100]\n\ninput |> List.skip 5                       // [36; 49; 64; 81; 100]\ninput |> List.skip 11                      // ArgumentException\n```\n\n### skipWhile (Array, List, Seq)\n\nReturns a collection, when iterated, skips elements of the underlying array (list, seq)\nwhile the given predicate returns true, and then yields the remaining elements.\n\n```fsharp\nlet mySeq = seq { for i in 1 .. 10 -> i * i }    // 1 4 9 16 25 36 49 64 81 100\n\nmySeq |> Seq.skipWhile (fun elem -> elem < 10)   // 16 25 36 49 64 81 100\nmySeq |> Seq.skipWhile (fun elem -> elem < 101)  // Empty seq\n```\n\n### exists (Array, List, Seq)\n\nTests if any element of the collection satisfies the given predicate.\n\n```fsharp\nlet inputs = [0..3]\n\ninputs |> List.exists (fun elem -> elem = 3)      // true\ninputs |> List.exists (fun elem -> elem = 10)     // false\n```\n\n### exists2 (Array, List, Seq)\n\nTests if any pair of corresponding elements of the collections satisfies\nthe given predicate. The collections must have equal lengths, except for Seq where extra elements are ignored.\n\n```fsharp\nlet list1to5 = [1 .. 5]           // [1; 2; 3; 4; 5]\nlet list0to4 = [0 .. 4]           // [0; 1; 2; 3; 4]\nlet list5to1 = [5 .. -1 .. 1]     // [5; 4; 3; 2; 1]\nlet list6to1 = [6 .. -1 .. 1]     // [6; 5; 4; 3; 2; 1]\n\n(list1to5, list5to1) ||> List.exists2 (fun i1 i2 -> i1 = i2)    // true\n(list1to5, list0to4) ||> List.exists2 (fun i1 i2 -> i1 = i2)    // false\n(list1to5, list6to1) ||> List.exists2 (fun i1 i2 -> i1 = i2)    // ArgumentException\n```\n\n### forall (Array, List, Seq)\n\nTests if all elements of the collection satisfy the given predicate.\n\n```fsharp\nlet inputs = [2; 4; 6; 8; 10]\n\ninputs |> List.forall (fun i -> i % 2 = 0)    // true\ninputs |> List.forall (fun i -> i % 2 = 0)    // false\n```\n\n### forall2 (Array, List, Seq)\n\nReturns true if all corresponding elements of the collection satisfy the given predicate pairwise.\nThe collections must have equal lengths, except for Seq where extra elements are ignored.\n\n```fsharp\nlet lst1 = [0; 1; 2]\nlet lst2 = [0; 1; 2]\nlet lst3 = [2; 1; 0]\nlet lst4 = [0; 1; 2; 3]\n\n(lst1, lst2) ||> List.forall2 (fun i1 i2 -> i1 = i2)    // true\n(lst1, lst3) ||> List.forall2 (fun i1 i2 -> i1 = i2)    // false\n(lst1, lst4) ||> List.forall2 (fun i1 i2 -> i1 = i2)    // ArgumentException\n```\n\n### contains (Array, List, Seq)\n\nReturns true if a collection contains an equal value:\n\n```fsharp\nlet rushSet = [\"Dirk\"; \"Lerxst\"; \"Pratt\"]\nlet gotSet = rushSet |> List.contains \"Lerxst\"      // true\n```\n\n### filter, where (Array, List, Seq)\n\nReturns a new collection containing only the elements of the collection\nfor which the given predicate returns true.\n\n```fsharp\nlet data =\n    [(\"Cats\",4)\n     (\"Tiger\",5)\n     (\"Mice\",3)\n     (\"Elephants\",2) ]\n\n// [(\"Cats\", 4); (\"Mice\", 3)]\ndata |> List.filter (fun (nm, x) -> nm.Length <= 4)\ndata |> List.where (fun (nm, x) -> nm.Length <= 4)\n```\n\n### length (Array, List, Seq)\n\nReturns the length of the collection.\n\n```fsharp\n[ 1 .. 100 ] |> List.length         // 100\n[ ] |> List.length                  // 0\n[ 1 .. 2 .. 100 ] |> List.length    // 50\n```\n\n### distinctBy (Array, List, Seq)\n\nReturns a collection that contains no duplicate entries according to the generic hash and\nequality comparisons on the keys returned by the given key-generating function.\n\n```fsharp\nlet inputs = [-5 .. 10]\n\n// [-5; -4; -3; -2; -1; 0; 6; 7; 8; 9; 10]\ninputs  |> List.distinctBy (fun i -> abs i)\n```\n\n### distinct (Array, List, Seq)    == Distinct() in LINQ\n\nReturns a collection that contains no duplicate entries according to generic hash and\nequality comparisons on the entries.\n\n```fsharp\n[1; 3; 9; 4; 3; 1] |> List.distinct    // [1; 3; 9; 4]\n[1; 1; 1; 1; 1; 1] |> List.distinct     // [1]\n[ ] |> List.distinct                    // error FS0030: Value restriction\n```\n\n### sortBy (Array, List, Seq)    == OrderBy() in LINQ\n\nSorts the given collection using keys given by the given projection.\nKeys are compared using *Operators.compare*.\n\n```fsharp\n[1; 4; 8; -2; 5] |> List.sortBy (fun x -> abs x)    // [1; -2; 4; 5; 8]\n```\n\n### sort (Array, List, Seq)\n\nSorts the given list using *Operators.compare*.\n\n```fsharp\n[1; 4; 8; -2; 5] |> List.sort    // [-2; 1; 4; 5; 8]\n```\n\n### sortByDescending (Array, List, Seq)\n\n```fsharp\n[-3..3] |> List.sortByDescending (fun x -> abs x)   // [-3; 3; -2; 2; -1; 1; 0]\n```\n\n### sortDescending (Array, List, Seq)\n\n```fsharp\n[0..5] |> List.sortDescending    // [5; 4; 3; 2; 1; 0]\n```\n\n### sortWith (Array, List, Seq)\n\nSorts the given collection using the given comparison function.\n\n```fsharp\nlet lst = [\"<>\"; \"&\"; \"&&\"; \"&&&\"; \"<\"; \">\"; \"|\"; \"||\"; \"|||\"]\n\nlet sortFunction (str1: string) (str2: string) =\n    if (str1.Length > str2.Length) then\n        1\n    else\n        -1\n\n// [\"|\"; \">\"; \"<\"; \"&\"; \"||\"; \"&&\"; \"<>\"; \"|||\"; \"&&&\"]\nlst |> List.sortWith sortFunction\n```\n\n<a name=\"ArrayListAndSeqFunctions\"></a>Array, List and Seq functions\n-------------------\n\n### allPairs (Array, List, Seq)\n\nTakes 2 arrays (list, seq), and returns all possible pairs of elements.\n\n```fsharp\nlet arr1 = [| 0; 1 |]\nlet arr2 = [| 4; 5 |]\n\n(arr1, arr2) ||> Array.allPairs arr1 arr2    // [|(0, 4); (0, 5); (1, 4); (1, 5)|]\n```\n\n### append (Array, List, Seq)\n\nCombines 2 arrays (list, seq).\n\n```fsharp\nlet list1 = [33; 5; 16]\nlet list2 = [42; 23; 18]\n\nList.append list1 list2     // [33; 5; 16; 42; 23; 18]\n```\n\n### averageBy (Array, List, Seq)\n\n*averageBy* take a function as a parameter, and this function's results are used\nto calculate the values for the average.\n\n```fsharp\n// val avg1 : float = 2.0\n[1..3] |> List.averageBy (fun elem -> float elem)\n\n// val avg2 : float = 4.666666667\n[| 1..3 |] |> Array.averageBy (fun elem -> float (elem * elem))\n```\n\n### Seq.cache\n\n*Seq.cache* creates a stored version of a sequence. Use *Seq.cache* to avoid reevaluation\nof a sequence, or when you have multiple threads that use a sequence,\nbut you must make sure that each element is acted upon only one time.\nWhen you have a sequence that is being used by multiple threads,\nyou can have one thread that enumerates and computes the values for the original sequence,\nand remaining threads can use the cached sequence.\n\n### choose (Array, List, Seq)\n\n*choose* enables you to transform and select elements at the same time.\n\n```fsharp\nlet list1 = [33; 5; 16]\n\n// [34; 6; 17]\nlist1 |> List.choose (fun elem -> Some(elem + 1)) \n```\n\n### compareWith (Array, List, Seq)\n\nCompare two arrays (lists, seq) by using the *compareWith* function.\nThe function compares successive elements in turn, and stops when it encounters\nthe first unequal pair. Any additional elements do not contribute to the comparison.\n\n```fsharp\nlet sq1 = seq { 1; 2; 4; 5; 7 }\nlet sq2 = seq { 1; 2; 3; 5; 8 }\nlet sq3 = seq { 1; 3; 3; 5; 2 }\n\nlet compareSeq seq1 seq2 =\n    (seq1, seq2 ||> Seq.compareWith (fun e1 e2 ->\n        if e1 > e2 then 1\n        elif e1 < e2 then -1\n        else 0)\n\nlet compareResult1 = compareSeq sq1 sq2     // int = 1\nlet compareResult2 = compareSeq sq2 sq3     // int = -1\n```\n\n### concat (Array, List, Seq)\n\n*concat* is used to join any number of arrays (lists, seq).\n\n```fsharp\n// int list = [1; 2; 3; 4; 5; 6; 7; 8; 9]\nList.concat [[1; 2; 3]; [4; 5; 6]; [7; 8; 9]]\n```\n\n### Array.copy\n\nCreates a new array that contains elements that are copied from an existing array.\n**The copy is a shallow copy**, which means that if the element type is a reference type,\nonly the reference is copied, not the underlying object. \n\n```fsharp\nlet firstArray : StringBuilder array = Array.init 3 (fun index -> new StringBuilder(\"\"))\nlet secondArray = Array.copy firstArray\n\nfirstArray.[0] <- new StringBuilder(\"Test1\")\nfirstArray[0] <- new StringBuilder(\"Test1\") // F# 6\n\nfirstArray.[1].Insert(0, \"Test2\") |> ignore\nfirstArray[1].Insert(0, \"Test2\") |> ignore // F# 6\n```\n"
  }
]