From ebf02b57e36a8090a6e40cf02a9f355594590a22 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Fri, 24 Aug 2018 06:18:48 -0400 Subject: [PATCH 01/24] Learning about asserts --- FSharpKoans/AboutAsserts.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FSharpKoans/AboutAsserts.fs b/FSharpKoans/AboutAsserts.fs index 3eba955a..c999ce8f 100755 --- a/FSharpKoans/AboutAsserts.fs +++ b/FSharpKoans/AboutAsserts.fs @@ -27,7 +27,7 @@ module ``about asserts`` = [] let AssertExpectation() = let expected_value = 1 + 1 - let actual_value = __ //start by changing this line + let actual_value = 2 //start by changing this line AssertEquality expected_value actual_value @@ -35,4 +35,4 @@ module ``about asserts`` = [] let FillInValues() = - AssertEquality (1 + 1) __ + AssertEquality (1 + 1) 2 From ae7e081f839929b898d1f09e7893e1f3ff5c4d61 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Fri, 24 Aug 2018 06:19:22 -0400 Subject: [PATCH 02/24] Learning about let --- FSharpKoans/AboutLet.fs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/FSharpKoans/AboutLet.fs b/FSharpKoans/AboutLet.fs index 7fd3e786..a107686a 100755 --- a/FSharpKoans/AboutLet.fs +++ b/FSharpKoans/AboutLet.fs @@ -15,7 +15,7 @@ module ``about let`` = let LetBindsANameToAValue() = let x = 50 - AssertEquality x __ + AssertEquality x 50 (* In F#, values created with let are inferred to have a type like "int" for integer values, "string" for text values, and "bool" @@ -28,7 +28,7 @@ module ``about let`` = let y = "a string" let expectedType = y.GetType() - AssertEquality expectedType typeof + AssertEquality expectedType typeof [] let YouCanMakeTypesExplicit() = @@ -38,8 +38,8 @@ module ``about let`` = let y:string = "forty two" let typeOfY = y.GetType() - AssertEquality typeOfX typeof - AssertEquality typeOfY typeof + AssertEquality typeOfX typeof + AssertEquality typeOfY typeof (* You don't usually need to provide explicit type annotations types for local variables, but type annotations can come in handy in other @@ -68,7 +68,7 @@ module ``about let`` = let mutable x = 100 x <- 200 - AssertEquality x __ + AssertEquality x 200 [] let YouCannotModifyALetBoundValueIfItIsNotMutable() = @@ -82,4 +82,4 @@ module ``about let`` = // to reuse the name of a value in some cases using "shadowing". let x = 100 - AssertEquality x __ + AssertEquality x 100 From d0468e73464b7130a1af66089e79251e10cc5b33 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Fri, 24 Aug 2018 06:34:48 -0400 Subject: [PATCH 03/24] Learning about functions --- FSharpKoans/AboutFunctions.fs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/FSharpKoans/AboutFunctions.fs b/FSharpKoans/AboutFunctions.fs index ab677934..278a8430 100755 --- a/FSharpKoans/AboutFunctions.fs +++ b/FSharpKoans/AboutFunctions.fs @@ -24,8 +24,8 @@ module ``about functions`` = let result1 = add 2 2 let result2 = add 5 2 - AssertEquality result1 __ - AssertEquality result2 __ + AssertEquality result1 4 + AssertEquality result2 7 [] let NestingFunctions() = @@ -36,7 +36,7 @@ module ``about functions`` = double(double(x)) let result = quadruple 4 - AssertEquality result __ + AssertEquality result 16 [] let AddingTypeAnnotations() = @@ -48,7 +48,7 @@ module ``about functions`` = text.Replace(" ", "") let auctioneered = sayItLikeAnAuctioneer "going once going twice sold to the lady in red" - AssertEquality auctioneered __ + AssertEquality auctioneered "goingoncegoingtwicesoldtotheladyinred" //TRY IT: What happens if you remove the type annotation on text? @@ -63,7 +63,7 @@ module ``about functions`` = let caffeinatedReply = caffeinate "hello there" - AssertEquality caffeinatedReply __ + AssertEquality caffeinatedReply "HELLO THERE!!!" (* NOTE: Accessing the suffix variable in the nested caffeinate function is known as a closure. From 0517efdfbb5dfb3d6f6c50d5fc2de824922c46eb Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Fri, 24 Aug 2018 06:41:46 -0400 Subject: [PATCH 04/24] Learning about evaluation ordering --- FSharpKoans/AboutTheOrderOfEvaluation.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FSharpKoans/AboutTheOrderOfEvaluation.fs b/FSharpKoans/AboutTheOrderOfEvaluation.fs index 803e749d..53eb7a3c 100755 --- a/FSharpKoans/AboutTheOrderOfEvaluation.fs +++ b/FSharpKoans/AboutTheOrderOfEvaluation.fs @@ -18,7 +18,7 @@ module ``about the order of evaluation`` = let result = add (add 5 8) (add 1 1) - AssertEquality result __ + AssertEquality result 15 (* TRY IT: What happens if you remove the parenthesis?*) @@ -32,4 +32,4 @@ module ``about the order of evaluation`` = let result = double <| add 5 8 - AssertEquality result __ + AssertEquality result 26 From b8b427ab9a91fb15885b1d538aa329c2fe6a002d Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Fri, 24 Aug 2018 06:46:15 -0400 Subject: [PATCH 05/24] Learning about unit --- FSharpKoans/AboutUnit.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FSharpKoans/AboutUnit.fs b/FSharpKoans/AboutUnit.fs index 201a5d8c..a5adc83e 100755 --- a/FSharpKoans/AboutUnit.fs +++ b/FSharpKoans/AboutUnit.fs @@ -19,7 +19,7 @@ module ``about unit`` = () let x = sendData "data" - AssertEquality x __ //Don't overthink this. Note also the value "()" displays as "null" in some cases. + AssertEquality x () //Don't overthink this. Note also the value "()" displays as "null" in some cases. [] let ParameterlessFunctionsTakeUnitAsTheirArgument() = @@ -27,4 +27,4 @@ module ``about unit`` = "hello" let result = sayHello() - AssertEquality result __ + AssertEquality result "hello" From 889e9e5d75d41e22f89f332ca0f46f8a48929452 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Fri, 24 Aug 2018 06:55:38 -0400 Subject: [PATCH 06/24] Learning about tuples --- FSharpKoans/AboutTuples.fs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/FSharpKoans/AboutTuples.fs b/FSharpKoans/AboutTuples.fs index 8ef786d1..4d5309f9 100755 --- a/FSharpKoans/AboutTuples.fs +++ b/FSharpKoans/AboutTuples.fs @@ -14,7 +14,7 @@ module ``about tuples`` = let CreatingTuples() = let items = ("apple", "dog") - AssertEquality items ("apple", __) + AssertEquality items ("apple", "dog") [] let AccessingTupleElements() = @@ -23,8 +23,8 @@ module ``about tuples`` = let fruit = fst items let animal = snd items - AssertEquality fruit __ - AssertEquality animal __ + AssertEquality fruit "apple" + AssertEquality animal "dog" [] let AccessingTupleElementsWithPatternMatching() = @@ -41,9 +41,9 @@ module ``about tuples`` = let fruit, animal, car = items - AssertEquality fruit __ - AssertEquality animal __ - AssertEquality car __ + AssertEquality fruit "apple" + AssertEquality animal "dog" + AssertEquality car "Mustang" [] let IgnoringValuesWithPatternMatching() = @@ -51,7 +51,7 @@ module ``about tuples`` = let _, animal, _ = items - AssertEquality animal __ + AssertEquality animal "dog" (* NOTE: pattern matching is found in many places throughout F#, and we'll revisit it again later *) @@ -64,8 +64,8 @@ module ``about tuples`` = let squared, cubed = squareAndCube 3.0 - AssertEquality squared __ - AssertEquality cubed __ + AssertEquality squared 9.0 + AssertEquality cubed 27.0 (* THINK ABOUT IT: Is there really more than one return value? What type does the squareAndCube function @@ -78,4 +78,4 @@ module ``about tuples`` = let result = squareAndCube 3.0 - AssertEquality result __ + AssertEquality result (9.0, 27.0) From c1576e09e1e4e2cf3fbbddf1517f56550b469e27 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Sat, 25 Aug 2018 07:33:49 -0400 Subject: [PATCH 07/24] Learning about strings --- FSharpKoans/AboutStrings.fs | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/FSharpKoans/AboutStrings.fs b/FSharpKoans/AboutStrings.fs index ec7a93f3..f8c38217 100755 --- a/FSharpKoans/AboutStrings.fs +++ b/FSharpKoans/AboutStrings.fs @@ -14,19 +14,19 @@ module ``about strings`` = let StringValue() = let message = "hello" - AssertEquality message __ + AssertEquality message "hello" [] let StringConcatValue() = let message = "hello " + "world" - AssertEquality message __ + AssertEquality message "hello world" [] let FormattingStringValues() = let message = sprintf "F# turns it to %d!" 11 - AssertEquality message __ + AssertEquality message "F# turns it to 11!" //NOTE: you can use printf to print to standard output @@ -37,13 +37,13 @@ module ``about strings`` = let FormattingOtherTypes() = let message = sprintf "hello %s" "world" - AssertEquality message __ + AssertEquality message "hello world" [] let FormattingAnything() = let message = sprintf "Formatting other types is as easy as: %A" (1, 2, 3) - AssertEquality message __ + AssertEquality message "Formatting other types is as easy as: (1, 2, 3)" (* NOTE: For all the %formatters that you can use with string formatting see: http://msdn.microsoft.com/en-us/library/ee370560.aspx *) @@ -56,7 +56,7 @@ module ``about strings`` = expiali\ docious" - AssertEquality message __ + AssertEquality message "supercalifragilisticexpialidocious" [] let Multiline() = @@ -67,7 +67,11 @@ module ``about strings`` = lines" AssertEquality - message __ + message "This + is + on + five + lines" [] let ExtractValues() = @@ -79,18 +83,24 @@ module ``about strings`` = (* A single character is denoted using single quotes, example: 'c', not double quotes as you would use for a string *) - AssertEquality first __ - AssertEquality other __ + AssertEquality first 'h' + AssertEquality other 'o' [] let ApplyWhatYouLearned() = (* It's time to apply what you've learned so far. Fill in the function below to make the asserts pass *) let getFunFacts x = - __ + let xD = x * 2 + let xT = x * 3 + (xD, xT) + + let funFactsAboutNum x = + let doubled, tripled = getFunFacts x + sprintf "%d doubled is %d, and %d tripled is %d!" x doubled x tripled - let funFactsAboutThree = getFunFacts 3 - let funFactsAboutSix = getFunFacts 6 + let funFactsAboutThree = funFactsAboutNum 3 + let funFactsAboutSix = funFactsAboutNum 6 - AssertEquality "3 doubled is 6, and 3 tripled is 9!" funFactsAboutThree + AssertEquality "3 doubled is 6, and 3 tripled is 9!" funFactsAboutThree AssertEquality "6 doubled is 12, and 6 tripled is 18!" funFactsAboutSix From 81f0bfe1a86c2f239ab6f1e1368d463955c0db39 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Sat, 25 Aug 2018 23:13:40 -0400 Subject: [PATCH 08/24] Learning about branching --- FSharpKoans/AboutBranching.fs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/FSharpKoans/AboutBranching.fs b/FSharpKoans/AboutBranching.fs index 9b1bc771..13428e5f 100755 --- a/FSharpKoans/AboutBranching.fs +++ b/FSharpKoans/AboutBranching.fs @@ -19,7 +19,7 @@ module ``about branching`` = "it's odd!" let result = isEven 2 - AssertEquality result __ + AssertEquality result "it's even!" [] let IfStatementsReturnValues() = @@ -34,7 +34,7 @@ module ``about branching`` = else "no problem here" - AssertEquality result __ + AssertEquality result "no problem here" [] let BranchingWithAPatternMatch() = @@ -46,8 +46,8 @@ module ``about branching`` = let result1 = isApple "apple" let result2 = isApple "" - AssertEquality result1 __ - AssertEquality result2 __ + AssertEquality result1 true + AssertEquality result2 false [] let UsingTuplesWithIfStatementsQuicklyBecomesClumsy() = @@ -64,8 +64,8 @@ module ``about branching`` = let person1 = ("Chris", "steak") let person2 = ("Dave", "veggies") - AssertEquality (getDinner person1) __ - AssertEquality (getDinner person2) __ + AssertEquality (getDinner person1) "Chris wants 'em some steak" + AssertEquality (getDinner person2) "Dave doesn't want red meat" [] let PatternMatchingIsNicer() = @@ -80,5 +80,5 @@ module ``about branching`` = let person1 = ("Bob", "fish") let person2 = ("Sally", "Burger") - AssertEquality (getDinner person1) __ - AssertEquality (getDinner person2) __ + AssertEquality (getDinner person1) "Bob doesn't want red meat" + AssertEquality (getDinner person2) "Sally wants 'em some Burger" From b7c2fc38431ff9c76c5ec687e49952d697667c19 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Sat, 25 Aug 2018 23:35:05 -0400 Subject: [PATCH 09/24] Learning about lists --- FSharpKoans/AboutLists.fs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/FSharpKoans/AboutLists.fs b/FSharpKoans/AboutLists.fs index c15543c5..693f4c48 100755 --- a/FSharpKoans/AboutLists.fs +++ b/FSharpKoans/AboutLists.fs @@ -21,9 +21,9 @@ module ``about lists`` = //Note: The list data type in F# is a singly linked list, // so indexing elements is O(n). - AssertEquality list.Head __ - AssertEquality list.Tail __ - AssertEquality list.Length __ + AssertEquality list.Head "apple" + AssertEquality list.Tail ["pear"; "grape"; "peach"] + AssertEquality list.Length 4 (* .NET developers coming from other languages may be surprised that F#'s list type is not the same as the base class library's @@ -42,8 +42,8 @@ module ``about lists`` = //Note: "::" is known as "cons" AssertEquality ["apple"; "pear"; "grape"; "peach"] third - AssertEquality second __ - AssertEquality first __ + AssertEquality second ["pear"; "grape"; "peach"] + AssertEquality first ["grape"; "peach"] //What happens if you uncomment the following? @@ -59,8 +59,8 @@ module ``about lists`` = let first = ["apple"; "pear"; "grape"] let second = first @ ["peach"] - AssertEquality first __ - AssertEquality second __ + AssertEquality first ["apple"; "pear"; "grape"] + AssertEquality second ["apple"; "pear"; "grape"; "peach"] (* THINK ABOUT IT: In general, what performs better for building lists, :: or @? Why? @@ -73,21 +73,21 @@ module ``about lists`` = let CreatingListsWithARange() = let list = [0..4] - AssertEquality list.Head __ - AssertEquality list.Tail __ + AssertEquality list.Head 0 + AssertEquality list.Tail [1;2;3;4] [] let CreatingListsWithComprehensions() = let list = [for i in 0..4 do yield i ] - AssertEquality list __ + AssertEquality list [0;1;2;3;4] [] let ComprehensionsWithConditions() = let list = [for i in 0..10 do if i % 2 = 0 then yield i ] - AssertEquality list __ + AssertEquality list [0;2;4;6;8;10] [] let TransformingListsWithMap() = @@ -97,8 +97,8 @@ module ``about lists`` = let original = [0..5] let result = List.map square original - AssertEquality original __ - AssertEquality result __ + AssertEquality original [0;1;2;3;4;5] + AssertEquality result [0;1;4;9;16;25] [] let FilteringListsWithFilter() = @@ -108,8 +108,8 @@ module ``about lists`` = let original = [0..5] let result = List.filter isEven original - AssertEquality original __ - AssertEquality result __ + AssertEquality original [0;1;2;3;4;5] + AssertEquality result [0;2;4] [] let DividingListsWithPartition() = @@ -119,8 +119,8 @@ module ``about lists`` = let original = [0..5] let result1, result2 = List.partition isOdd original - AssertEquality result1 __ - AssertEquality result2 __ + AssertEquality result1 [1;3;5] + AssertEquality result2 [0;2;4] (* Note: There are many other useful methods in the List module. Check them via intellisense in Visual Studio by typing '.' after List, or online at From 9afef5a719706ad99ae06e04effa02be2e6c2acf Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Sun, 26 Aug 2018 21:47:01 -0400 Subject: [PATCH 10/24] Learning about Pipelining --- FSharpKoans/AboutPipelining.fs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/FSharpKoans/AboutPipelining.fs b/FSharpKoans/AboutPipelining.fs index 3fa1d0f3..885fcdfd 100755 --- a/FSharpKoans/AboutPipelining.fs +++ b/FSharpKoans/AboutPipelining.fs @@ -20,14 +20,14 @@ module ``about pipelining`` = [] let SquareEvenNumbersWithSeparateStatements() = (* One way to combine the operations is by using separate statements. - However, this is can be clumsy since you have to name each result. *) + However, this can be clumsy since you have to name each result. *) let numbers = [0..5] let evens = List.filter isEven numbers let result = List.map square evens - AssertEquality result __ + AssertEquality result [0; 4; 16] [] let SquareEvenNumbersWithParens() = @@ -39,7 +39,7 @@ module ``about pipelining`` = let result = List.map square (List.filter isEven numbers) - AssertEquality result __ + AssertEquality result [0; 4; 16] [] let SquareEvenNumbersWithPipelineOperator() = @@ -51,7 +51,7 @@ module ``about pipelining`` = |> List.filter isEven |> List.map square - AssertEquality result __ + AssertEquality result [0; 4; 16] [] let HowThePipeOperatorIsDefined() = @@ -63,4 +63,4 @@ module ``about pipelining`` = |> List.filter isEven |> List.map square - AssertEquality result __ + AssertEquality result [0; 4; 16] From 2743f1ba38155a3f8aee94771170b06857d73bc7 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Sun, 26 Aug 2018 22:09:32 -0400 Subject: [PATCH 11/24] Learning about arrays --- FSharpKoans/AboutArrays.fs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/FSharpKoans/AboutArrays.fs b/FSharpKoans/AboutArrays.fs index 2014706d..a392936d 100755 --- a/FSharpKoans/AboutArrays.fs +++ b/FSharpKoans/AboutArrays.fs @@ -13,9 +13,9 @@ module ``about arrays`` = let CreatingArrays() = let fruits = [| "apple"; "pear"; "peach"|] - AssertEquality fruits.[0] __ - AssertEquality fruits.[1] __ - AssertEquality fruits.[2] __ + AssertEquality fruits.[0] "apple" + AssertEquality fruits.[1] "pear" + AssertEquality fruits.[2] "peach" [] let ArraysAreDotNetArrays() = @@ -33,7 +33,7 @@ module ``about arrays`` = let fruits = [| "apple"; "pear" |] fruits.[1] <- "peach" - AssertEquality fruits __ + AssertEquality fruits [| "apple"; "peach" |] [] let YouCanCreateArraysWithComprehensions() = @@ -41,7 +41,7 @@ module ``about arrays`` = [| for i in 0..10 do if i % 2 = 0 then yield i |] - AssertEquality numbers __ + AssertEquality numbers [| 0; 2; 4; 6; 8; 10 |] [] let ThereAreAlsoSomeOperationsYouCanPerformOnArrays() = @@ -51,5 +51,5 @@ module ``about arrays`` = let original = [| 0..5 |] let result = Array.map cube original - AssertEquality original __ - AssertEquality result __ + AssertEquality original [| 0..5 |] + AssertEquality result [| 0; 1; 8; 27; 64; 125 |] From a59e25fa0388b3d2070ed871dcf157d37229b0dd Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Sun, 26 Aug 2018 22:15:42 -0400 Subject: [PATCH 12/24] Learning about looping --- FSharpKoans/AboutLooping.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FSharpKoans/AboutLooping.fs b/FSharpKoans/AboutLooping.fs index 2dc6fc49..1a7a43cd 100755 --- a/FSharpKoans/AboutLooping.fs +++ b/FSharpKoans/AboutLooping.fs @@ -19,7 +19,7 @@ module ``about looping`` = for value in values do sum <- sum + value - AssertEquality sum __ + AssertEquality sum 55 [] let LoopingWithExpressions() = @@ -28,7 +28,7 @@ module ``about looping`` = for i = 1 to 5 do sum <- sum + i - AssertEquality sum __ + AssertEquality sum 15 [] let LoopingWithWhile() = @@ -37,7 +37,7 @@ module ``about looping`` = while sum < 10 do sum <- sum + sum - AssertEquality sum __ + AssertEquality sum 16 (* NOTE: While these looping constructs can come in handy from time to time, it's often better to use a more functional approach for looping From f52d337fbba6f7be3bc8d49264075ebf5fef88f4 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Mon, 27 Aug 2018 22:50:59 -0400 Subject: [PATCH 13/24] Learning about functions --- FSharpKoans/MoreAboutFunctions.fs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/FSharpKoans/MoreAboutFunctions.fs b/FSharpKoans/MoreAboutFunctions.fs index 817b77e3..05f6de24 100755 --- a/FSharpKoans/MoreAboutFunctions.fs +++ b/FSharpKoans/MoreAboutFunctions.fs @@ -20,7 +20,7 @@ module ``more about functions`` = colors |> List.map (fun x -> x + " " + x) - AssertEquality echo __ + AssertEquality echo ["maize maize"; "blue blue"] (* The fun keyword allows you to create a function inline without giving it a name. These functions are known as anonymous functions, lambdas, @@ -36,14 +36,14 @@ module ``more about functions`` = (* F#'s lightweight syntax allows you to call both functions as if there was only one *) let simpleResult = add 2 4 - AssertEquality simpleResult __ + AssertEquality simpleResult 6 (* ...but you can also pass only one argument at a time to create residual functions. This technique is known as partial application. *) let addTen = add 10 let fancyResult = addTen 14 - AssertEquality fancyResult __ + AssertEquality fancyResult 24 //NOTE: Functions written in this style are said to be curried. @@ -58,8 +58,8 @@ module ``more about functions`` = let unluckyNumber = addSeven 6 let luckyNumber = addSeven 0 - AssertEquality unluckyNumber __ - AssertEquality luckyNumber __ + AssertEquality unluckyNumber 13 + AssertEquality luckyNumber 7 [] let NonCurriedFunctions() = @@ -76,7 +76,7 @@ module ``more about functions`` = let result = add(5, 40) - AssertEquality result __ + AssertEquality result 45 (* THINK ABOUT IT: You learned earlier that functions with multiple return values are really just functions that return From 093d84e05211121bf568613c5441634ee8d03fa8 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Mon, 27 Aug 2018 22:51:13 -0400 Subject: [PATCH 14/24] Learning about DotNet Collections --- FSharpKoans/AboutDotNetCollections.fs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/FSharpKoans/AboutDotNetCollections.fs b/FSharpKoans/AboutDotNetCollections.fs index e24eeabc..1df2778d 100755 --- a/FSharpKoans/AboutDotNetCollections.fs +++ b/FSharpKoans/AboutDotNetCollections.fs @@ -19,8 +19,8 @@ module ``about dot net collections`` = fruits.Add("apple") fruits.Add("pear") - AssertEquality fruits.[0] __ - AssertEquality fruits.[1] __ + AssertEquality fruits.[0] "apple" + AssertEquality fruits.[1] "pear" [] let CreatingDotNetDictionaries() = @@ -29,8 +29,8 @@ module ``about dot net collections`` = addressBook.["Chris"] <- "Ann Arbor" addressBook.["SkillsMatter"] <- "London" - AssertEquality addressBook.["Chris"] __ - AssertEquality addressBook.["SkillsMatter"] __ + AssertEquality addressBook.["Chris"] "Ann Arbor" + AssertEquality addressBook.["SkillsMatter"] "London" [] let YouUseCombinatorsWithDotNetTypes() = @@ -49,15 +49,15 @@ module ``about dot net collections`` = // that you can combine to perform operations on types implementing // seq/IEnumerable. - AssertEquality verboseBook.[0] __ - AssertEquality verboseBook.[1] __ + AssertEquality verboseBook.[0] "Name: Chris - City: Ann Arbor" + AssertEquality verboseBook.[1] "Name: SkillsMatter - City: London" [] let SkippingElements() = let original = [0..5] - let result = Seq.skip 2 original + let result = Seq.skip 2 original |> Seq.toList - AssertEquality result __ + AssertEquality result [2; 3; 4; 5] [] let FindingTheMax() = @@ -71,7 +71,7 @@ module ``about dot net collections`` = let result = Seq.max values - AssertEquality result __ + AssertEquality result 20 [] let FindingTheMaxUsingACondition() = @@ -81,4 +81,4 @@ module ``about dot net collections`` = let names = [| "Harry"; "Lloyd"; "Nicholas"; "Mary"; "Joe"; |] let result = Seq.maxBy getNameLength names - AssertEquality result __ + AssertEquality result "Nicholas" From b188574d9c261474d7146e22a669362218979d9f Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Tue, 28 Aug 2018 07:39:13 -0400 Subject: [PATCH 15/24] Putting all of the learning together so far --- FSharpKoans/AboutTheStockExample.fs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/FSharpKoans/AboutTheStockExample.fs b/FSharpKoans/AboutTheStockExample.fs index c9ae49cf..8982c238 100755 --- a/FSharpKoans/AboutTheStockExample.fs +++ b/FSharpKoans/AboutTheStockExample.fs @@ -58,8 +58,30 @@ module ``about the stock example`` = // tests for yourself along the way. You can also try // using the F# Interactive window to check your progress. + let splitOnComma (x:string) = + x.Split([|','|]) + + let parseD (x:string) = + System.Convert.ToDouble x + + let getDiffAndDateFromValues (x:string[]) = + match x with + | [| date; openS; high; low; closeS; volume; adjClose |] -> + let diff = abs ((parseD openS) - (parseD closeS)) + (date, diff) + | _ -> failwith "Input array size is not 7 elements!" + [] let YouGotTheAnswerCorrect() = - let result = __ + let rawData = stockData |> Seq.skip 1 + + let resDate, _ = + stockData + |> Seq.skip 1 + |> Seq.map (splitOnComma >> getDiffAndDateFromValues) + |> Seq.sortByDescending (fun (d, m) -> m) + |> Seq.head + + let result = resDate - AssertEquality "2012-03-13" result + AssertEquality "2012-03-13" result \ No newline at end of file From 67920f5a029b16534c62e93881da4bbc6ce0562c Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Tue, 28 Aug 2018 07:42:53 -0400 Subject: [PATCH 16/24] Learning about record types --- FSharpKoans/AboutRecordTypes.fs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/FSharpKoans/AboutRecordTypes.fs b/FSharpKoans/AboutRecordTypes.fs index 93332168..cf30a4aa 100755 --- a/FSharpKoans/AboutRecordTypes.fs +++ b/FSharpKoans/AboutRecordTypes.fs @@ -20,19 +20,19 @@ module ``about record types`` = let RecordsHaveProperties() = let mario = { Name = "Mario"; Occupation = "Plumber"; } - AssertEquality mario.Name __ - AssertEquality mario.Occupation __ + AssertEquality mario.Name "Mario" + AssertEquality mario.Occupation "Plumber" [] let CreatingFromAnExistingRecord() = let mario = { Name = "Mario"; Occupation = "Plumber"; } let luigi = { mario with Name = "Luigi"; } - AssertEquality mario.Name __ - AssertEquality mario.Occupation __ + AssertEquality mario.Name "Mario" + AssertEquality mario.Occupation "Plumber" - AssertEquality luigi.Name __ - AssertEquality luigi.Occupation __ + AssertEquality luigi.Name "Luigi" + AssertEquality luigi.Occupation "Plumber" [] let ComparingRecords() = @@ -52,8 +52,8 @@ module ``about record types`` = else "he is still kind of a koopa" - AssertEquality koopaComparison __ - AssertEquality bowserComparison __ + AssertEquality koopaComparison "all the koopas are pretty much the same" + AssertEquality bowserComparison "he is still kind of a koopa" [] let YouCanPatternMatchAgainstRecords() = @@ -66,6 +66,6 @@ module ``about record types`` = | { Occupation = "Plumber" } -> "good guy" | _ -> "bad guy" - AssertEquality (determineSide mario) __ - AssertEquality (determineSide luigi) __ - AssertEquality (determineSide bowser) __ + AssertEquality (determineSide mario) "good guy" + AssertEquality (determineSide luigi) "good guy" + AssertEquality (determineSide bowser) "bad guy" From d21b9072c8287e13c6d220c02f49b562dde8e9c2 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Wed, 29 Aug 2018 14:35:36 -0400 Subject: [PATCH 17/24] Modified for continuous integration build support --- FSharpKoans/PathToEnlightenment.fs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/FSharpKoans/PathToEnlightenment.fs b/FSharpKoans/PathToEnlightenment.fs index ceef9a84..cb410ef8 100755 --- a/FSharpKoans/PathToEnlightenment.fs +++ b/FSharpKoans/PathToEnlightenment.fs @@ -1,4 +1,5 @@ -open FSharpKoans +open System +open FSharpKoans open FSharpKoans.Core let runner = KoanRunner() @@ -17,10 +18,13 @@ match result with printfn "" printfn "Please meditate on the following code:" printfn "%s" ex.StackTrace - + Environment.ExitCode <- 1 + printfn "" printfn "" printfn "" printfn "" +(* printf "Press any key to continue..." System.Console.ReadKey() |> ignore +*) From 14d01149e36fae9985dc84c280319293bc415fc8 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Wed, 29 Aug 2018 14:35:49 -0400 Subject: [PATCH 18/24] Learning about option types --- FSharpKoans/AboutOptionTypes.fs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/FSharpKoans/AboutOptionTypes.fs b/FSharpKoans/AboutOptionTypes.fs index fd38dded..eae55513 100755 --- a/FSharpKoans/AboutOptionTypes.fs +++ b/FSharpKoans/AboutOptionTypes.fs @@ -22,17 +22,17 @@ module ``about option types`` = let OptionTypesMightContainAValue() = let someValue = Some 10 - AssertEquality someValue.IsSome __ - AssertEquality someValue.IsNone __ - AssertEquality someValue.Value __ + AssertEquality someValue.IsSome true + AssertEquality someValue.IsNone false + AssertEquality someValue.Value 10 [] let OrTheyMightNot() = let noValue = None - AssertEquality noValue.IsSome __ - AssertEquality noValue.IsNone __ - AssertThrows (fun () -> noValue.Value) + AssertEquality noValue.IsSome false + AssertEquality noValue.IsNone true + AssertThrows (fun () -> noValue.Value) [] let UsingOptionTypesWithPatternMatching() = From 58633a7779ed17494efa9ed360cd9898707d40f7 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Wed, 29 Aug 2018 17:47:16 -0400 Subject: [PATCH 19/24] Learning about Some OptionTypes --- FSharpKoans/AboutOptionTypes.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FSharpKoans/AboutOptionTypes.fs b/FSharpKoans/AboutOptionTypes.fs index eae55513..a2fc5dfa 100755 --- a/FSharpKoans/AboutOptionTypes.fs +++ b/FSharpKoans/AboutOptionTypes.fs @@ -53,8 +53,8 @@ module ``about option types`` = | Some score -> translate score | None -> "Unknown" - AssertEquality (getScore chronoTrigger) __ - AssertEquality (getScore halo) __ + AssertEquality (getScore chronoTrigger) "Great" + AssertEquality (getScore halo) "Unknown" [] let ProjectingValuesFromOptionTypes() = From b7c90665a5bec7b39283e272a66562b48ddc0cc9 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Wed, 29 Aug 2018 18:00:37 -0400 Subject: [PATCH 20/24] Enlightenment on Option Types --- FSharpKoans/AboutOptionTypes.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FSharpKoans/AboutOptionTypes.fs b/FSharpKoans/AboutOptionTypes.fs index a2fc5dfa..4dcf1769 100755 --- a/FSharpKoans/AboutOptionTypes.fs +++ b/FSharpKoans/AboutOptionTypes.fs @@ -67,5 +67,5 @@ module ``about option types`` = |> Option.map (fun score -> if score > 3 then "play it" else "don't play") //HINT: look at the return type of the decide on function - AssertEquality (decideOn chronoTrigger) __ - AssertEquality (decideOn halo) __ + AssertEquality (decideOn chronoTrigger) (Some "play it") + AssertEquality (decideOn halo) None From c150fa9163c5996249b9ebc3cb5bf9e95e2df79f Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Tue, 4 Sep 2018 23:38:30 -0400 Subject: [PATCH 21/24] Learning about classes --- FSharpKoans/AboutClasses.fs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/FSharpKoans/AboutClasses.fs b/FSharpKoans/AboutClasses.fs index 350ec440..fb18f697 100755 --- a/FSharpKoans/AboutClasses.fs +++ b/FSharpKoans/AboutClasses.fs @@ -43,14 +43,14 @@ module ``about classes`` = let ClassesCanHaveProperties() = let zombie = new Zombie() - AssertEquality zombie.FavoriteFood __ + AssertEquality zombie.FavoriteFood "brains" [] let ClassesCanHaveMethods() = let zombie = new Zombie() let result = zombie.Eat "brains" - AssertEquality result __ + AssertEquality result "mmmmmmmmmmmmmmm" [] let ClassesCanHaveConstructors() = @@ -58,14 +58,14 @@ module ``about classes`` = let person = new Person("Shaun") let result = person.Speak() - AssertEquality result __ + AssertEquality result "Hi my name is Shaun" [] let ClassesCanHaveLetBindingsInsideThem() = let zombie = new Zombie2() let result = zombie.Eat "chicken" - AssertEquality result __ + AssertEquality result "grrrrrrrr" (* TRY IT: Can you access the let bound value Zombie2.favoriteFood outside of the class definition? *) @@ -75,8 +75,8 @@ module ``about classes`` = let person = new Person2("Shaun") let firstPhrase = person.Speak() - AssertEquality firstPhrase __ + AssertEquality firstPhrase "Hi my name is Shaun" person.Name <- "Shaun of the Dead" let secondPhrase = person.Speak() - AssertEquality secondPhrase __ + AssertEquality secondPhrase "Hi my name is Shaun of the Dead" From 3e44d479c5c4da3b06e33604da9943dc0c5fe8ef Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Tue, 4 Sep 2018 23:38:51 -0400 Subject: [PATCH 22/24] Learning about discriminated unions --- FSharpKoans/AboutDiscriminatedUnions.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FSharpKoans/AboutDiscriminatedUnions.fs b/FSharpKoans/AboutDiscriminatedUnions.fs index 5a7645c5..1e723dfe 100755 --- a/FSharpKoans/AboutDiscriminatedUnions.fs +++ b/FSharpKoans/AboutDiscriminatedUnions.fs @@ -33,7 +33,7 @@ module ``about discriminated unions`` = let choice = Mustard - AssertEquality (toColor choice) __ + AssertEquality (toColor choice) "yellow" (* TRY IT: What happens if you remove a case from the above pattern match? *) @@ -51,5 +51,5 @@ module ``about discriminated unions`` = let bourbonResult = saySomethingAboutYourFavorite <| Bourbon "Maker's Mark" let numberResult = saySomethingAboutYourFavorite <| Number 7 - AssertEquality bourbonResult __ - AssertEquality numberResult __ + AssertEquality bourbonResult "I prefer Bookers to Maker's Mark" + AssertEquality numberResult "me too!" From ede943231cecf239e09005e914ff4a15a063ab24 Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Tue, 4 Sep 2018 23:42:17 -0400 Subject: [PATCH 23/24] Learning about modules --- FSharpKoans/AboutModules.fs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/FSharpKoans/AboutModules.fs b/FSharpKoans/AboutModules.fs index a53aaeed..7a28bbf5 100755 --- a/FSharpKoans/AboutModules.fs +++ b/FSharpKoans/AboutModules.fs @@ -31,17 +31,17 @@ module ``about modules`` = [] let ModulesCanContainValuesAndTypes() = - AssertEquality MushroomKingdom.Mario.Name __ - AssertEquality MushroomKingdom.Mario.Occupation __ + AssertEquality MushroomKingdom.Mario.Name "Mario" + AssertEquality MushroomKingdom.Mario.Occupation "Plumber" let moduleType = MushroomKingdom.Mario.GetType() - AssertEquality moduleType typeof + AssertEquality moduleType typeof [] let ModulesCanContainFunctions() = let superMario = MushroomKingdom.powerUp MushroomKingdom.Mario - AssertEquality superMario.Power __ + AssertEquality superMario.Power (Some MushroomKingdom.Power.Mushroom) (* NOTE: In previous sections, you've seen modules like List and Option that contain useful functions for dealing with List types and Option types @@ -53,6 +53,6 @@ open MushroomKingdom module ``about opened modules`` = [] let OpenedModulesBringTheirContentsInScope() = - AssertEquality Mario.Name __ - AssertEquality Mario.Occupation __ - AssertEquality Mario.Power __ \ No newline at end of file + AssertEquality Mario.Name "Mario" + AssertEquality Mario.Occupation "Plumber" + AssertEquality Mario.Power None \ No newline at end of file From f5ee4ecb9b84174b52d9f4ec29c66182c7c8d77f Mon Sep 17 00:00:00 2001 From: "Norman H. Harebottle III" Date: Tue, 4 Sep 2018 23:55:18 -0400 Subject: [PATCH 24/24] Learning about filtering --- FSharpKoans/AboutFiltering.fs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/FSharpKoans/AboutFiltering.fs b/FSharpKoans/AboutFiltering.fs index 0aa1244f..621bc07d 100644 --- a/FSharpKoans/AboutFiltering.fs +++ b/FSharpKoans/AboutFiltering.fs @@ -31,7 +31,7 @@ module ``about filtering`` = names |> List.filter (fun name -> name.StartsWith( "A" )) - AssertEquality actual_names [ __ ] + AssertEquality actual_names [ "Alice" ] //Or passing a function to filter let startsWithTheLetterB (s: string) = @@ -41,18 +41,18 @@ module ``about filtering`` = names |> List.filter startsWithTheLetterB - AssertEquality namesBeginningWithB [ __ ] + AssertEquality namesBeginningWithB [ "Bob" ] [] let FindingJustOneItem() = - let names = [ "Alice"; "Bob"; "Eve"; ] + let names = [ "Alice"; "Bob"; "Eve" ] let expected_name = "Bob" // find will return just one item, or throws an exception let actual_name = names - |> List.find (fun name -> name = __ ) + |> List.find (fun name -> name = "Bob" ) //??? What would happen if there are 2 Bobs in the List? @@ -70,8 +70,8 @@ module ``about filtering`` = names |> List.tryFind (fun name -> name = "Zelda" ) - AssertEquality eve.IsSome __ - AssertEquality zelda.IsSome __ + AssertEquality eve.IsSome true + AssertEquality zelda.IsSome false [] let ChoosingItemsFromAList() = @@ -83,7 +83,7 @@ module ``about filtering`` = numbers |> List.choose someIfEven - AssertEquality evenNumbers [ __ ] + AssertEquality evenNumbers [ 2 ] //You can also use the "id" function on types of 'a option list //"id" will return just those that are "Some" @@ -94,7 +94,7 @@ module ``about filtering`` = |> List.choose id //Notice the type of namesWithValue is 'string list', whereas optionNames is 'string option list' - AssertEquality namesWithValue [ __ ] + AssertEquality namesWithValue [ "Alice" ] [] let PickingItemsFromAList() = @@ -106,7 +106,7 @@ module ``about filtering`` = numbers |> List.pick someIfEven - AssertEquality firstEven __ + AssertEquality firstEven 6 //As with choose, you can also use the "id" function on types of 'a option list //to return just those that are "Some" @@ -116,6 +116,6 @@ module ``about filtering`` = optionNames |> List.pick id - AssertEquality firstNameWithValue __ + AssertEquality firstNameWithValue "Alice" //There is also a tryPick which works like tryFind, returning "None" instead of throwing an exception.