### F# OWIN WebAPI Client and Server Setup Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/low-risk-ways-to-use-fsharp-at-work.md Demonstrates setting up an OWIN self-host server with WebAPI and then consuming it using an HttpClient in F#. Includes example API responses. ```F# use app = Microsoft.Owin.Hosting.WebApp.Start(url=baseAddress) // Create client and make some requests to the api use client = new System.Net.Http.HttpClient() let showResponse query = let response = client.GetAsync(baseAddress + query).Result Console.WriteLine(response) Console.WriteLine(response.Content.ReadAsStringAsync().Result) showResponse "api/greeting" showResponse "api/values" showResponse "api/values/42" // for standalone scripts, pause so that you can test via your browser as well Console.ReadLine() |> ignore ``` -------------------------------- ### F# Stack Constants: EMPTY and START Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/stack-based-calculator.md Defines the `EMPTY` stack and initializes `START` to an empty stack. ```fsharp let EMPTY = StackContents [] let START = EMPTY ``` -------------------------------- ### F# List.length Example Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/list-module-functions.md A straightforward example showing how to get the number of elements in an F# list using List.length. ```fsharp [1..10] |> List.length // 10 ``` -------------------------------- ### Setup World Bank Data Context in F# Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/low-risk-ways-to-use-fsharp-at-work-5.md Initializes the World Bank Data type provider by setting the current directory and referencing the FSharp.Data assembly. This setup is required before querying any World Bank data. ```fsharp System.IO.Directory.SetCurrentDirectory (__SOURCE_DIRECTORY__) // Requires FSharp.Data under script directory // nuget install FSharp.Data -o Packages -ExcludeVersion #r @"Packages\FSharp.Data\lib\net40\FSharp.Data.dll" open FSharp.Data let data = WorldBankData.GetDataContext() ``` -------------------------------- ### F# Class Declaration Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Demonstrates the F# syntax for declaring a simple class using the 'type' keyword, followed by the class name and parentheses. More complex definitions require further discussion. ```fsharp type MyClassName() = // class members here ``` -------------------------------- ### FsCheck QuickCheck Example (F#) Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/property-based-testing-2.md Demonstrates how to use FsCheck's Check.Quick function to run property-based tests. This example shows how to pass a property function and a sorting implementation to QuickCheck to verify the property against the implementation. ```fsharp let goodSort = List.sort Check.Quick (``adjacent pairs from a list should be ordered`` goodSort) ``` ```fsharp let goodSort = List.sort Check.Quick (``adjacent pairs from a list should be ordered`` goodSort) ``` ```fsharp Check.Quick (``adjacent pairs from a string list should be ordered`` goodSort) ``` ```fsharp let badSort aList = [] Check.Quick (``adjacent pairs from a list should be ordered`` badSort) ``` -------------------------------- ### F# return Function Implementation Examples Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/elevated-world.md Examples of the 'return' function, also known as 'unit' or 'pure', which lifts a single value into an elevated world. These examples demonstrate lifting a value into the world of Options and Lists in F#. ```fsharp (* A value lifted to the world of Options *) let returnOption x = Some x (* has type : 'a -> 'a option *) (* A value lifted to the world of Lists *) let returnList x = [x] (* has type : 'a -> 'a list *) ``` -------------------------------- ### F# Example Workflow with Refactored TurtleProgram Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/13-ways-of-looking-at-a-turtle-2.md Illustrates an example F# workflow, `drawTwoLines`, using the refactored helper functions and computation expressions. It demonstrates creating and executing a simple sequence of turtle movements. ```fsharp let handleMoveResponse log moveResponse = turtleProgram { ... // as before // example let drawTwoLines log = turtleProgram { let! response = move 60.0 do! handleMoveResponse log response let! response = move 60.0 do! handleMoveResponse log response } ``` -------------------------------- ### F# Testing Array Parser Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/understanding-parser-combinators-4.md Provides examples of testing the F# `jArray` parser after fixing the `jValueRef`. The first example shows successful parsing of a simple numeric array. The second example demonstrates error handling when an unexpected trailing comma is present in the array input. ```fsharp run jArray "[ 1, 2 ]" // Success (JArray [JNumber 1.0; JNumber 2.0], ``` ```fsharp run jArray "[ 1, 2, ]" |> printResult // Line:0 Col:6 Error parsing array // [ 1, 2, ] // ^Unexpected ',' ``` -------------------------------- ### C# Squarer Class Example Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md A C# class named 'Squarer' with methods to calculate the square of an integer and print the result to the console. This serves as a baseline for porting to F#. ```csharp using System; using System.Collections.Generic; namespace PortingToFsharp { public class Squarer { public int Square(int input) { var result = input * input; return result; } public void PrintSquare(int input) { var result = this.Square(input); Console.WriteLine("Input={0}. Result={1}", input, result); } } } ``` -------------------------------- ### F#: Example Product Data Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/recursive-types-and-folds-1b.md Provides example instances of the 'Product' domain types defined previously. This includes simple 'Bought' products like labels and bottles, and more complex 'Made' products like shampoo and a two-pack, demonstrating the recursive nature of the domain. ```fsharp let label = Bought {name="label"; weight=1; vendor=Some "ACME"} let bottle = Bought {name="bottle"; weight=2; vendor=Some "ACME"} let formulation = Bought {name="formulation"; weight=3; vendor=None} let shampoo = Made {name="shampoo"; weight=10; components= [ {qty=1; product=formulation} {qty=1; product=bottle} {qty=2; product=label} ]} let twoPack = Made {name="twoPack"; weight=5; components= [ {qty=2; product=shampoo} ]} ``` -------------------------------- ### F# Example: Download and Display Good URI Content Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/elevated-world-5.md Demonstrates how to use the `getUriContent` and `showContentResult` functions in F# to download content from a valid URI ('http://google.com') and display the result. The download is run synchronously using `Async.RunSynchronously` for interactive testing. ```F# System.Uri ("http://google.com") |> getUriContent |> Async.RunSynchronously |> showContentResult // [google.com] Started ... // [google.com] ... finished // SUCCESS: [google.com] First 100 chars: (state)*10 + x) [1;2;3;4] 0 // [4321; 432; 43; 4; 0] <=== accumulates from right ``` -------------------------------- ### F# Function to Setup API Test Data Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/elevated-world-6.md This F# function, setupTestData, configures an ApiClient with sample purchase and product information. It sets up data for customers C1 and C2, and products P1 and P2, noting that P3 is intentionally missing. The function is designed to be used within an ApiAction for execution. ```fsharp let setupTestData (api:ApiClient) = //setup purchases api.Set (CustId "C1") [ProductId "P1"; ProductId "P2"] |> ignore api.Set (CustId "C2") [ProductId "PX"; ProductId "P2"] |> ignore //setup product info api.Set (ProductId "P1") {ProductName="P1-Name"} |> ignore api.Set (ProductId "P2") {ProductName="P2-Name"} |> ignore // P3 missing // setupTestData is an api-consuming function // so it can be put in an ApiAction // and then that apiAction can be executed let setupAction = ApiAction setupTestData ApiAction.execute setupAction ``` -------------------------------- ### Emulating Map and Apply with Bind in F# Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/elevated-world-2.md Provides F# code examples demonstrating how the 'map' and 'apply' functions can be defined using 'Option.bind' and 'return'. This illustrates the greater power of bind, showing it can construct other fundamental functional operations. ```fsharp // map defined in terms of bind and return (Some) let map f = Option.bind (f >> Some) // apply defined in terms of bind and return (Some) let apply fOpt xOpt = fOpt |> Option.bind (fun f -> let map = Option.bind (f >> Some) map xOpt) ``` -------------------------------- ### Define DUP, SWAP, START Helpers in F# Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/stack-based-calculator.md These F# functions provide core stack manipulation utilities: DUP duplicates the top element, SWAP exchanges the top two elements, and START initializes an empty stack. Dependencies: pop, push functions. ```fsharp /// Duplicate the top value on the stack let DUP stack = // get the top of the stack let x,_ = pop stack // push it onto the stack again push x stack /// Swap the top two values let SWAP stack = let x,s = pop stack let y,s' = pop s push y (push x s') /// Make an obvious starting point let START = EMPTY ``` -------------------------------- ### F# List.fold Example: Integer Summation Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/list-module-functions.md Illustrates the F# List.fold function for summing a list of integers, starting with an initial state. This is a common use case for accumulating a numerical result. ```fsharp [1;2;3] |> List.fold (+) 10 // 16 // 10 + 1 + 2 + 3 ``` -------------------------------- ### F# List.max, List.min, List.maxBy, List.minBy Examples Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/list-module-functions.md Shows how to find the maximum and minimum elements in an F# list, both directly and based on a specific key using List.maxBy and List.minBy. ```fsharp type Suit = Club | Diamond | Spade | Heart type Rank = Two | Three | King | Ace let cards = [ (Club,King); (Diamond,Ace); (Spade,Two); (Heart,Three); ] cards |> List.max // (Heart, Three) cards |> List.maxBy snd // (Diamond, Ace) cards |> List.min // (Club, King) cards |> List.minBy snd // (Spade, Two) ``` -------------------------------- ### F# 'Trace' Workflow Execution Examples Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/computation-expressions-builder-part1.md Shows sample F# code demonstrating the execution of the 'trace' computation expression with different scenarios. It includes examples of returning a value, returning a wrapped value using 'return!', and using 'let!' to bind unwrapped and potentially 'None' values, illustrating the workflow's behavior with 'Option' types. ```fsharp trace { return 1 } |> printfn "Result 1: %A" trace { return! Some 2 } |> printfn "Result 2: %A" trace { let! x = Some 1 let! y = Some 2 return x + y } |> printfn "Result 3: %A" trace { let! x = None let! y = Some 1 return x + y } |> printfn "Result 4: %A" ``` -------------------------------- ### F# Create an Empty Stack Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/stack-based-calculator.md Defines a constant `EMPTY` to represent an empty stack, initialized with an empty list. This serves as the starting point for stack operations. ```fsharp let EMPTY = StackContents [] ``` -------------------------------- ### F# Typed Value Declaration Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Shows how to declare an F# value with an explicit type annotation. The type is specified after the value name, preceded by a colon. ```fsharp let variableName: int = 42 ``` -------------------------------- ### Configure and Create Main Form in F# Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/capability-based-security.md Sets up capabilities for the main form by retrieving message flag and background color functionalities from the Configuration subsystem. It then creates and displays the main form, ensuring sensitive data like connection strings are not passed to it. ```fsharp module Startup = // set up capabilities let configCapabilities = Config.configurationCapabilities let formCapabilities = configCapabilities.GetMessageFlag, configCapabilities.SetMessageFlag, configCapabilities.GetBackgroundColor, configCapabilities.SetBackgroundColor // start let form = UserInterface.createMainForm formCapabilities form.ShowDialog() |> ignore ``` -------------------------------- ### F# Function Call Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Illustrates calling an F# function. Parentheses and commas are not used for parameter separation; whitespace is sufficient. This applies to both defining and calling functions. ```fsharp let result = Square input ``` -------------------------------- ### F# Inequality Test Operator Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Demonstrates the F# operator for testing inequality. F# uses '<>' for inequality, which is equivalent to '!=' in C#. Using '!=' in F# results in an error (FS0020). ```fsharp let variableName = 42 // Bound to 42 on declaration variableName <> 43 // Comparison will return true. variableName != 43 // Error FS0020. ``` -------------------------------- ### F# Composition vs Piping for Squaring Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/stack-based-calculator.md Demonstrates the difference between creating a composed function for squaring a number using `>>` (composition) and attempting to pipe with `|>` which requires a concrete stack instance. ```fsharp let COMPOSED_SQUARE = DUP >> MUL let PIPED_SQUARE = DUP |> MUL // This causes a compilation error. // To use piping, a concrete stack instance is needed: let stackWith2 = EMPTY |> TWO let twoSquared = stackWith2 |> DUP |> MUL ``` -------------------------------- ### F# Implicit Return Value Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Explains that in F#, the last expression in a block is implicitly returned, eliminating the need for an explicit 'return' keyword. This is a consequence of F#'s expression-based nature. ```fsharp let Square input = let result = input * input result ``` -------------------------------- ### F# Examples: Testing the `largestFile` Function Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/recursive-types-and-folds-2b.md These F# code examples demonstrate how to use the `largestFile` function on different file system structures (`readme`, `src`, `bin`, `root`) and show the expected output, including cases where the largest file is found or where the directory is empty. ```fsharp readme |> largestFile // Some {name = "readme.txt"; fileSize = 1} src |> largestFile // Some {name = "build.bat"; fileSize = 3} bin |> largestFile // None root |> largestFile // Some {name = "build.bat"; fileSize = 3} ``` -------------------------------- ### Test Stack Push Function (F#) Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/stack-based-calculator.md Provides example code to test the `push` function by creating an empty stack and then pushing values onto it sequentially, demonstrating the function's correct behavior. ```fsharp let emptyStack = StackContents [] let stackWith1 = push 1.0 emptyStack let stackWith2 = push 2.0 stackWith1 ``` -------------------------------- ### F# Mutable Automatic Property Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/classes.md Shows the syntax for a mutable automatic property in F# (available starting in VS2012). This allows for easy declaration of properties with both 'get' and 'set' accessors without manual backing field management. ```fsharp member val MyProp = initialValue with get,set ``` -------------------------------- ### F# Function Signature with Inferred Types Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Illustrates a typical F# function signature where type inference is used, omitting explicit type annotations for parameters and return values. This is the more common and concise F# style. ```fsharp let Square input = ... code ... ``` -------------------------------- ### Create and Extract Stack Contents (F#) Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/stack-based-calculator.md Demonstrates how to create a new stack using the `StackContents` constructor and how to extract the underlying list of floats from a stack using pattern matching. ```fsharp let newStack = StackContents [1.0;2.0;3.0] let (StackContents contents) = newStack // "contents" value set to // float list = [1.0; 2.0; 3.0] ``` -------------------------------- ### Complete Capability-Based Security Example - F# Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/capability-based-security.md Presents a full, albeit crude, example of a capability-based security system implemented in F#. The application features a window with a main region and buttons to interact with capabilities for setting message flags and background colors. ```fsharp (* A complete example in F# (also available as a gist here: https://gist.github.com/swlaschin/909c5b24bf921e5baa8c#file-capabilitybasedsecurity_configexample-fsx) *) (* This example consists of a simple window with a main region and some extra buttons. * If you click in the main area, an annoying dialog pops up with a "don't show this message again" option. * One of the buttons allows you to change the background color using the system color picker, and store it in the config. * The other button allows you to reset the "don't show this message again" option back to false. It's very crude and very ugly -- no UI designers were hurt in the making of it -- but it should demonstrate the main points so far. *) (* Image: Example application ../assets/img/auth_annoying_popup.png *) ``` -------------------------------- ### F# Mutable Variable Assignment Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Shows how to declare and mutate variables in F#. Values are immutable by default and require the 'mutable' keyword. Assignment to mutable variables uses the '<-' operator, unlike C# which uses '='. ```csharp var variableName = 42 variableName = variableName + 1 ``` ```fsharp let mutable variableName = 42 variableName <- variableName + 1 ``` -------------------------------- ### F# List vs C# Array Initialization Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Demonstrates the difference in initializing lists or arrays between F# and C#. F# uses semicolons to separate elements in a list, while C# uses commas for array initialization. ```csharp var list = new int[] { 1,2,3} ``` ```fsharp let list = [1;2;3] // semicolons ``` -------------------------------- ### F# Initial Implementation of getPurchaseInfo Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/elevated-world-6.md The first attempt at implementing the `getPurchaseInfo` function in F#. It initializes an API client, fetches product IDs for a customer, and outlines the structure for getting product information, but lacks proper error handling and result processing. ```fsharp let getPurchaseInfo (custId:CustId) : Result = // Open api connection use api = new ApiClient() api.Open() // Get product ids purchased by customer id let productIdsResult = api.Get custId let productInfosResult = ?? // Close api connection api.Close() // Return the list of product infos productInfosResult ``` -------------------------------- ### F# Property with Private Setter Accessibility Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/classes.md Illustrates how to define a property in F# where the setter has different accessibility than the getter. This example shows a 'public get, private set' scenario, although F# often favors immutability for cleaner designs. ```fsharp type AccessibilityExample2() = let mutable privateValue = 42 member this.PrivateSetProperty with get() = privateValue and private set(value) = privateValue <- value // test let a2 = new AccessibilityExample2(); printf "%i" a2.PrivateSetProperty // ok to read // a2.PrivateSetProperty <- 43 // not ok to write ``` -------------------------------- ### F# WebAPI Owin Self-Host Setup and Controllers Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/low-risk-ways-to-use-fsharp-at-work.md This F# script sets up and runs a self-hosted Owin WebAPI application. It includes necessary assembly references, defines controllers (GreetingController and ValuesController), and configures the HTTP configuration for routing and JSON serialization. It also includes a custom `ControllerResolver` to handle controller discovery in interactive F# scripts. ```fsharp // sets the current directory to be same as the script directory System.IO.Directory.SetCurrentDirectory (__SOURCE_DIRECTORY__) // assumes nuget install Microsoft.AspNet.WebApi.OwinSelfHost has been run // so that assemblies are available under the current directory #r @"Packages\Owin\lib\net40\Owin.dll" #r @"Packages\Microsoft.Owin\lib\net40\Microsoft.Owin.dll" #r @"Packages\Microsoft.Owin.Host.HttpListener\lib\net40\Microsoft.Owin.Host.HttpListener.dll" #r @"Packages\Microsoft.Owin.Hosting\lib\net40\Microsoft.Owin.Hosting.dll" #r @"Packages\Microsoft.AspNet.WebApi.Owin\lib\net45\System.Web.Http.Owin.dll" #r @"Packages\Microsoft.AspNet.WebApi.Core\lib\net45\System.Web.Http.dll" #r @"Packages\Microsoft.AspNet.WebApi.Client\lib\net45\System.Net.Http.Formatting.dll" #r @"Packages\Newtonsoft.Json\lib\net40\Newtonsoft.Json.dll" #r "System.Net.Http.dll" open System open Owin open Microsoft.Owin open System.Web.Http open System.Web.Http.Dispatcher open System.Net.Http.Formatting module OwinSelfhostSample = /// a record to return [] type Greeting = { Text : string } /// A simple Controller type GreetingController() = inherit ApiController() // GET api/greeting member this.Get() = {Text="Hello!"} /// Another Controller that parses URIs type ValuesController() = inherit ApiController() // GET api/values member this.Get() = ["value1";"value2"] // GET api/values/5 member this.Get id = sprintf "id is %i" id // POST api/values member this.Post ([]value:string) = () // PUT api/values/5 member this.Put(id:int, []value:string) = () // DELETE api/values/5 member this.Delete(id:int) = () /// A helper class to store routes, etc. type ApiRoute = { id : RouteParameter } /// IMPORTANT: When running interactively, the controllers will not be found with error: /// "No type was found that matches the controller named 'XXX'." /// The fix is to override the ControllerResolver to use the current assembly type ControllerResolver() = inherit DefaultHttpControllerTypeResolver() override this.GetControllerTypes (assembliesResolver:IAssembliesResolver) = let t = typeof System.Reflection.Assembly.GetExecutingAssembly().GetTypes() |> Array.filter t.IsAssignableFrom :> Collections.Generic.ICollection /// A class to manage the configuration type MyHttpConfiguration() as this = inherit HttpConfiguration() let configureRoutes() = this.Routes.MapHttpRoute( name= "DefaultApi", routeTemplate= "api/{controller}/{id}", defaults= { id = RouteParameter.Optional } ) |> ignore let configureJsonSerialization() = let jsonSettings = this.Formatters.JsonFormatter.SerializerSettings jsonSettings.Formatting <- Newtonsoft.Json.Formatting.Indented jsonSettings.ContractResolver <- Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() // Here is where the controllers are resolved let configureServices() = this.Services.Replace( typeof, new ControllerResolver()) do configureRoutes() do configureJsonSerialization() do configureServices() /// Create a startup class using the configuration type Startup() = // This code configures Web API. The Startup class is specified as a type // parameter in the WebApp.Start method. member this.Configuration (appBuilder:IAppBuilder) = // Configure Web API for self-host. let config = new MyHttpConfiguration() appBuilder.UseWebApi(config) |> ignore // Start OWIN host do // Create server let baseAddress = "http://localhost:9000/" ``` -------------------------------- ### F# Value Declaration Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Demonstrates F# value declaration using the 'let' keyword, similar to 'var' in C#. F# values must be initialized upon declaration, and immutability is the default. The 'mutable' keyword is required for reassignment. ```fsharp let result = input * input ``` -------------------------------- ### F#: Interactive Product Weight Calculation Tests Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/recursive-types-and-folds-1b.md Shows interactive tests for the `productWeight` function using previously defined product examples. The tests verify the correctness of the weight calculation for simple and complex nested products. ```fsharp label |> productWeight // 1 shampoo |> productWeight // 17 = 10 + (2x1 + 1x2 + 1x3) twoPack |> productWeight // 39 = 5 + (2x17) ``` -------------------------------- ### F# Function with 'unit' Return Type Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Converts a C# 'void' method to an F# function. While 'unit' explicitly represents the absence of a meaningful return value, F# often infers this and omits the explicit type annotation. ```fsharp let PrintSquare (input: int): unit = ... code ... ``` ```fsharp let PrintSquare input = ... code ... ``` -------------------------------- ### F# Dollar Class Interactive Usage Example Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/property-based-testing-2.md Demonstrates interactive usage of the F# Dollar class, showing how to create an instance and call its methods. This is for exploration and verification before formal testing. ```fsharp let d = Dollar.Create 2 d.Amount // 2 d.Times 3 d.Amount // 6 d.Add 1 d.Amount // 7 ``` -------------------------------- ### Nest Asynchronous Workflows in F# Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/concurrency-async-and-parallel.md Illustrates how to nest asynchronous workflows within each other. The 'let!' syntax is used to block on child workflows, allowing the parent workflow to wait for their completion. The example shows a parent workflow starting a child workflow and then waiting for its result. ```fsharp let sleepWorkflow = async{ printfn "Starting sleep workflow at %O" DateTime.Now.TimeOfDay do! Async.Sleep 2000 printfn "Finished sleep workflow at %O" DateTime.Now.TimeOfDay } let nestedWorkflow = async{ printfn "Starting parent" let! childWorkflow = Async.StartChild sleepWorkflow // give the child a chance and then keep working do! Async.Sleep 100 printfn "Doing something useful while waiting " // block on the child let! result = childWorkflow // done printfn "Finished parent" } // run the whole workflow Async.RunSynchronously nestedWorkflow ``` -------------------------------- ### F# Computation Expression Example with Return Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/computation-expressions-builder-part3.md Demonstrates a simple computation expression in F# using the 'return' keyword multiple times. This snippet showcases basic usage of the builder pattern within computation expressions. ```fsharp trace { return 1 return 2 return 3 } |> printfn "Result for return x 3: %A" ``` -------------------------------- ### F# Calculator Configuration and Services Implementation Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/calculator-complete-v1.md Implements the `CalculatorConfiguration` and `CalculatorServices` modules. The configuration module defines a `Configuration` record and a `loadConfig` function. The services module provides functions for updating the display, handling numbers, performing math operations, and initializing the calculator state. These services are parameterized by the configuration. ```fsharp // ================================= ================ // Implementation of CalculatorConfiguration // ================================= ================ module CalculatorConfiguration = // A record to store configuration options // (e.g. loaded from a file or environment) type Configuration = { decimalSeparator : string divideByZeroMsg : string maxDisplayLength: int } let loadConfig() = { decimalSeparator = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator divideByZeroMsg = "ERR-DIV0" maxDisplayLength = 10 } // ================================= ================ // Implementation of CalculatorServices // ================================= ================ module CalculatorServices = open CalculatorDomain open CalculatorConfiguration let updateDisplayFromDigit (config:Configuration) :UpdateDisplayFromDigit = fun (digit, display) -> // determine what character should be appended to the display let appendCh= match digit with | Zero -> // only allow one 0 at start of display if display="0" then "" else "0" | One -> "1" | Two -> "2" | Three-> "3" | Four -> "4" | Five -> "5" | Six-> "6" | Seven-> "7" | Eight-> "8" | Nine-> "9" | DecimalSeparator -> if display="" then // handle empty display with special case "0" + config.decimalSeparator else if display.Contains(config.decimalSeparator) then // don't allow two decimal separators "" else config.decimalSeparator // ignore new input if there are too many digits if (display.Length > config.maxDisplayLength) then display // ignore new input else // append the new char display + appendCh let getDisplayNumber :GetDisplayNumber = fun display -> match System.Double.TryParse display with | true, d -> Some d | false, _ -> None let setDisplayNumber :SetDisplayNumber = fun f -> sprintf "%g" f let setDisplayError divideByZeroMsg :SetDisplayError = fun f -> match f with | DivideByZero -> divideByZeroMsg let doMathOperation :DoMathOperation = fun (op,f1,f2) -> match op with | Add -> Success (f1 + f2) | Subtract -> Success (f1 - f2) | Multiply -> Success (f1 * f2) | Divide -> try Success (f1 / f2) with | :? System.DivideByZeroException -> Failure DivideByZero let initState :InitState = fun () -> { display="" pendingOp = None } let createServices (config:Configuration) = { updateDisplayFromDigit = updateDisplayFromDigit config doMathOperation = doMathOperation getDisplayNumber = getDisplayNumber setDisplayNumber = setDisplayNumber setDisplayError = setDisplayError (config.divideByZeroMsg) initState = initState } ``` -------------------------------- ### F# Namespace Declaration Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Converts C# 'namespace' with curly braces to F# 'namespace'. F# generally uses filenames as default namespaces, with explicit declarations for .NET interop. The namespace declaration must precede other statements like 'open'. ```fsharp namespace MyNamespace open System ``` -------------------------------- ### F# Squarer Equivalent Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md This F# code provides an equivalent implementation to the C# 'Squarer' class. It defines functions within a type to calculate the square of an integer and print the result to the console using printf, demonstrating F#'s type-safe printing. ```fsharp namespace PortingToFsharp open System open System.Collections.Generic type Squarer() = let Square input = let result = input * input result let PrintSquare input = let result = Square input printf "Input=%i. Result=%i" input result ``` -------------------------------- ### F# Map Usage Examples with Options and Lists Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/elevated-world.md Illustrates practical usage of the 'map' function in F# for Options and Lists. Examples show creating lifted functions using partial application and directly applying 'map' to transform data. These demonstrate common F# idioms for functional programming. ```fsharp // Define a function in the normal world let add1 x = x + 1 // has type : int -> int // A function lifted to the world of Options let add1IfSomething = Option.map add1 // has type : int option -> int option // A function lifted to the world of Lists let add1ToEachElement = List.map add1 // has type : int list -> int list // With these mapped versions in place you can write code like this: Some 2 |> add1IfSomething // Some 3 [1;2;3] |> add1ToEachElement // [2; 3; 4] // In many cases, we don't bother to create an intermediate function -- partial application is used instead: Some 2 |> Option.map add1 // Some 3 [1;2;3] |> List.map add1 // [2; 3; 4] ``` -------------------------------- ### F# Equality Test vs. C# Assignment Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Highlights the difference in using the equals sign for equality testing in F# versus assignment in C#. F# uses '=' for comparison and initial binding, and '<-' for mutation. C# uses '=' for assignment and '==' for equality. ```fsharp let mutable variableName = 42 // Bound to 42 on declaration variableName <- variableName + 1 // Mutated (reassigned) variableName = variableName + 1 // Comparison not assignment! ``` -------------------------------- ### F# vs C# Function Parameter Syntax Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Illustrates the syntax for defining functions with parameters in F# compared to C#. F# uses whitespace to separate parameters, while C# uses commas within parentheses. Type annotations are optional in F# for simple cases. ```csharp int myFunc(int x, int y, int z) { ... function body ...} ``` ```fsharp let myFunc (x:int) (y:int) (z:int) :int = ... function body ... let myFunc x y z = ... function body ... ``` -------------------------------- ### F# Chain Stack Push Operations Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/stack-based-calculator.md Demonstrates function composition by chaining push operations using the pipe operator (`|>`). This allows for creating stacks with multiple elements in a readable, sequential manner, starting from an empty stack. Assumes `ONE`, `TWO`, `THREE` functions and `EMPTY` stack are defined. ```fsharp let result123 = EMPTY |> ONE |> TWO |> THREE let result312 = EMPTY |> THREE |> ONE |> TWO ``` -------------------------------- ### Example Usage Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/list-module-functions.md Illustrates the usage of both unsafe and safe functions for accessing list elements, highlighting exception handling and option types. ```APIDOC ## Usage Examples ### Unsafe Access Example ```fsharp let list = [1; 2; 3] let headElement = List.head list // val headElement : int = 1 // This will throw an exception: // let emptyList = [] // let badHead = List.head emptyList // System.ArgumentException ``` ### Safe Access Example ```fsharp let list = [1; 2; 3] let goodHeadOpt = List.tryHead list // val goodHeadOpt : int option = Some 1 let emptyList = [] let badHeadOpt = List.tryHead emptyList // val badHeadOpt : int option = None let goodItemOpt = List.tryItem 2 list // val goodItemOpt : int option = Some 3 let badItemOpt = List.tryItem 99 list // val badItemOpt : int option = None ``` ### Avoiding `item` for List Iteration *Incorrect approach (inefficient): ```fsharp // Don't do this! let helloBad = let list = ["a";"b";"c"] let listSize = List.length list [ for i in [0..listSize-1] do let element = list |> List.item i yield "hello " + element ] // val helloBad : string list = ["hello a"; "hello b"; "hello c"] ``` *Recommended approach (concise and efficient): ```fsharp let helloGood = let list = ["a";"b";"c"] list |> List.map (fun element -> "hello " + element) // val helloGood : string list = ["hello a"; "hello b"; "hello c"] ``` ``` -------------------------------- ### F# Function Signature with Explicit Types Source: https://github.com/swlaschin/fsharpforfunandprofit.gitbook/blob/master/posts/porting-to-csharp-getting-started.md Shows how to define an F# function with explicit type annotations for parameters and return values. Parameters are separated by whitespace, types follow a colon, and the return type is prefixed with a colon after all parameters. Parentheses are used to group parameter-type pairs. ```fsharp let Square (input: int): int = ... code ... ```