Created
April 19, 2020 23:27
-
-
Save amatiasq/258e6aeb70065a05151b395d018a8fd4 to your computer and use it in GitHub Desktop.
Created with Fable REPL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html, body { | |
margin: 0; | |
padding: 0; | |
background-color: black; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Tour.Functions | |
// From https://docs.microsoft.com/en-us/dotnet/fsharp/tour | |
// Visit the link above for more information on each topic | |
// You can also find more learning resources at https://fsharp.org/ | |
module BasicFunctions = | |
/// You use 'let' to define a function. This one accepts an integer argument and returns an integer. | |
/// Parentheses are optional for function arguments, except for when you use an explicit type annotation. | |
let sampleFunction1 x = x*x + 3 | |
/// Apply the function, naming the function return result using 'let'. | |
/// The variable type is inferred from the function return type. | |
let result1 = sampleFunction1 4573 | |
// This line uses '%d' to print the result as an integer. This is type-safe. | |
// If 'result1' were not of type 'int', then the line would fail to compile. | |
printfn "The result of squaring the integer 4573 and adding 3 is %d" result1 | |
/// When needed, annotate the type of a parameter name using '(argument:type)'. Parentheses are required. | |
let sampleFunction2 (x:int) = 2*x*x - x/5 + 3 | |
let result2 = sampleFunction2 (7 + 4) | |
printfn "The result of applying the 2nd sample function to (7 + 4) is %d" result2 | |
/// Conditionals use if/then/elif/else. | |
/// | |
/// Note that F# uses white space indentation-aware syntax, similar to languages like Python. | |
let sampleFunction3 x = | |
if x < 100.0 then | |
2.0*x*x - x/5.0 + 3.0 | |
else | |
2.0*x*x + x/5.0 - 37.0 | |
let result3 = sampleFunction3 (6.5 + 4.5) | |
// This line uses '%f' to print the result as a float. As with '%d' above, this is type-safe. | |
printfn "The result of applying the 2nd sample function to (6.5 + 4.5) is %f" result3 | |
module Immutability = | |
/// Binding a value to a name via 'let' makes it immutable. | |
/// | |
/// The second line of code fails to compile because 'number' is immutable and bound. | |
/// Re-defining 'number' to be a different value is not allowed in F#. | |
let number = 2 | |
// let number = 3 | |
/// A mutable binding. This is required to be able to mutate the value of 'otherNumber'. | |
let mutable otherNumber = 2 | |
printfn "'otherNumber' is %d" otherNumber | |
// When mutating a value, use '<-' to assign a new value. | |
// | |
// Note that '=' is not the same as this. '=' is used to test equality. | |
otherNumber <- otherNumber + 1 | |
printfn "'otherNumber' changed to be %d" otherNumber | |
module PipelinesAndComposition = | |
/// Squares a value. | |
let square x = x * x | |
/// Adds 1 to a value. | |
let addOne x = x + 1 | |
/// Tests if an integer value is odd via modulo. | |
let isOdd x = x % 2 <> 0 | |
/// A list of 5 numbers. More on lists later. | |
let numbers = [ 1; 2; 3; 4; 5 ] | |
/// Given a list of integers, it filters out the even numbers, | |
/// squares the resulting odds, and adds 1 to the squared odds. | |
let squareOddValuesAndAddOne values = | |
let odds = List.filter isOdd values | |
let squares = List.map square odds | |
let result = List.map addOne squares | |
result | |
printfn "processing %A through 'squareOddValuesAndAddOne' produces: %A" numbers (squareOddValuesAndAddOne numbers) | |
/// A shorter way to write 'squareOddValuesAndAddOne' is to nest each | |
/// sub-result into the function calls themselves. | |
/// | |
/// This makes the function much shorter, but it's difficult to see the | |
/// order in which the data is processed. | |
let squareOddValuesAndAddOneNested values = | |
List.map addOne (List.map square (List.filter isOdd values)) | |
printfn "processing %A through 'squareOddValuesAndAddOneNested' produces: %A" numbers (squareOddValuesAndAddOneNested numbers) | |
/// A preferred way to write 'squareOddValuesAndAddOne' is to use F# pipe operators. | |
/// This allows you to avoid creating intermediate results, but is much more readable | |
/// than nesting function calls like 'squareOddValuesAndAddOneNested' | |
let squareOddValuesAndAddOnePipeline values = | |
values | |
|> List.filter isOdd | |
|> List.map square | |
|> List.map addOne | |
printfn "processing %A through 'squareOddValuesAndAddOnePipeline' produces: %A" numbers (squareOddValuesAndAddOnePipeline numbers) | |
/// You can shorten 'squareOddValuesAndAddOnePipeline' by moving the second `List.map` call | |
/// into the first, using a Lambda Function. | |
/// | |
/// Note that pipelines are also being used inside the lambda function. F# pipe operators | |
/// can be used for single values as well. This makes them very powerful for processing data. | |
let squareOddValuesAndAddOneShorterPipeline values = | |
values | |
|> List.filter isOdd | |
|> List.map(fun x -> x |> square |> addOne) | |
printfn "processing %A through 'squareOddValuesAndAddOneShorterPipeline' produces: %A" numbers (squareOddValuesAndAddOneShorterPipeline numbers) | |
module RecursiveFunctions = | |
/// This example shows a recursive function that computes the factorial of an | |
/// integer. It uses 'let rec' to define a recursive function. | |
let rec factorial n = | |
if n = 0 then 1 else n * factorial (n-1) | |
printfn "Factorial of 6 is: %d" (factorial 6) | |
/// Computes the greatest common factor of two integers. | |
/// | |
/// Since all of the recursive calls are tail calls, | |
/// the compiler will turn the function into a loop, | |
/// which improves performance and reduces memory consumption. | |
let rec greatestCommonFactor a b = | |
if a = 0 then b | |
elif a < b then greatestCommonFactor a (b - a) | |
else greatestCommonFactor (a - b) b | |
printfn "The Greatest Common Factor of 300 and 620 is %d" (greatestCommonFactor 300 620) | |
/// This example computes the sum of a list of integers using recursion. | |
let rec sumList xs = | |
match xs with | |
| [] -> 0 | |
| y::ys -> y + sumList ys | |
/// This makes 'sumList' tail recursive, using a helper function with a result accumulator. | |
let rec private sumListTailRecHelper accumulator xs = | |
match xs with | |
| [] -> accumulator | |
| y::ys -> sumListTailRecHelper (accumulator+y) ys | |
/// This invokes the tail recursive helper function, providing '0' as a seed accumulator. | |
/// An approach like this is common in F#. | |
let sumListTailRecursive xs = sumListTailRecHelper 0 xs | |
let oneThroughTen = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] | |
printfn "The sum 1-10 is %d" (sumListTailRecursive oneThroughTen) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"> | |
</head> | |
<body> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment