Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filterign koans #34

Merged
merged 3 commits into from Jun 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 3 additions & 8 deletions .gitignore
@@ -1,9 +1,4 @@
FSharpKoans.Core/bin/
FSharpKoans.Core/obj/
FSharpKoans/bin/
FSharpKoans/obj/
FSharpKoans.Test/bin/
FSharpKoans.Test/obj/
FSharpKoans2008.suo
FSharpKoans2010.suo
[Bb]in/
[Oo]bj/
*.suo
packages/
24 changes: 19 additions & 5 deletions FSharpKoans.Core/FsharpKoans.Core.fsproj
Expand Up @@ -14,6 +14,8 @@
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<TargetFSharpCoreVersion>4.3.0.0</TargetFSharpCoreVersion>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand All @@ -34,9 +36,19 @@
<WarningLevel>3</WarningLevel>
<DocumentationFile>bin\Release\FSharpKoans.Core.XML</DocumentationFile>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')" />
<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="(!Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')) And (Exists('$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets'))" />
<Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="(!Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')) And (!Exists('$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets')) And (Exists('$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets'))" />
<Choose>
<When Condition="'$(VisualStudioVersion)' == '11.0'">
<PropertyGroup>
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
<ItemGroup>
<Compile Include="KoanAttribute.fs" />
<Compile Include="Helpers.fs" />
Expand All @@ -46,8 +58,10 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="FSharp.Core" />
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.5.10.11092\lib\nunit.framework.dll</HintPath>
<Private>True</Private>
Expand All @@ -71,4 +85,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
24 changes: 19 additions & 5 deletions FSharpKoans.Test/FSharpKoans.Test.fsproj
Expand Up @@ -12,6 +12,8 @@
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<Name>FSharpKoans.Test</Name>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<TargetFSharpCoreVersion>4.3.0.0</TargetFSharpCoreVersion>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand All @@ -32,18 +34,30 @@
<WarningLevel>3</WarningLevel>
<DocumentationFile>bin\Release\FSharpKoans.Test.XML</DocumentationFile>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')" />
<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="(!Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')) And (Exists('$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets'))" />
<Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="(!Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')) And (!Exists('$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets')) And (Exists('$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets'))" />
<Choose>
<When Condition="'$(VisualStudioVersion)' == '11.0'">
<PropertyGroup>
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
<ItemGroup>
<Compile Include="FindingKoans.fs" />
<Compile Include="RunningKoans.fs" />
<Compile Include="GettingTheWholeOutput.fs" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="FSharp.Core" />
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.5.10.11092\lib\nunit.framework.dll</HintPath>
<Private>True</Private>
Expand Down Expand Up @@ -74,4 +88,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
28 changes: 15 additions & 13 deletions FSharpKoans.sln
@@ -1,6 +1,8 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsharpKoans.Core", "FSharpKoans.Core\FsharpKoans.Core.fsproj", "{71460AA5-7357-4F1C-99BC-54244B50B00E}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharpKoans", "FSharpKoans\FSharpKoans.fsproj", "{87C025E8-3E63-4A20-B1CA-2E346D0E0C51}"
Expand All @@ -19,18 +21,6 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|x64.ActiveCfg = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|x86.ActiveCfg = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|Any CPU.Build.0 = Release|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|x64.ActiveCfg = Release|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|x86.ActiveCfg = Release|Any CPU
{71460AA5-7357-4F1C-99BC-54244B50B00E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{71460AA5-7357-4F1C-99BC-54244B50B00E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{71460AA5-7357-4F1C-99BC-54244B50B00E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
Expand All @@ -55,6 +45,18 @@ Global
{87C025E8-3E63-4A20-B1CA-2E346D0E0C51}.Release|x64.ActiveCfg = Release|x86
{87C025E8-3E63-4A20-B1CA-2E346D0E0C51}.Release|x86.ActiveCfg = Release|x86
{87C025E8-3E63-4A20-B1CA-2E346D0E0C51}.Release|x86.Build.0 = Release|x86
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|x64.ActiveCfg = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Debug|x86.ActiveCfg = Debug|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|Any CPU.Build.0 = Release|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|x64.ActiveCfg = Release|Any CPU
{69F00CBF-0EDC-4260-B852-C53B8C44BBCE}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
121 changes: 121 additions & 0 deletions FSharpKoans/AboutFiltering.fs
@@ -0,0 +1,121 @@
namespace FSharpKoans
open FSharpKoans.Core

module NumberFilterer =

let someIfPositive x =
if x % 2 = 0 then Some x
else None

//---------------------------------------------------------------
// Getting Started with Filtering Lists
//
// Lists in F# can be filtered in a number of ways.
// This koan looks at:
// - filter
// - find / tryFind
// - choose
// - pick
//---------------------------------------------------------------

[<Koan(Sort = 22)>]
module ``about filtering`` =
open NumberFilterer

[<Koan>]
let FilteringAList() =
let names = [ "Alice"; "Bob"; "Eve"; ]

// Find all the names starting with "A" using an anonymous function
let actual_names =
names
|> List.filter (fun name -> name.StartsWith( "A" ))

AssertEquality actual_names [ __ ]

//Or passing a function to filter
let startsWithTheLetterB (s: string) =
s.StartsWith("B")

let namesBeginningWithB =
names
|> List.filter startsWithTheLetterB

AssertEquality namesBeginningWithB [ __ ]

[<Koan>]
let FindingJustOneItem() =
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 = __ )

//??? What would happen if there are 2 Bob's in the List?

AssertEquality expected_name actual_name

[<Koan>]
let FindingJustOneOrZeroItem() =
let names = [ "Alice"; "Bob"; "Eve"; ]

// tryFind returns an option so you can handle 0 rows returned
let eve =
names
|> List.tryFind (fun name -> name = "Eve" )
let zelda =
names
|> List.tryFind (fun name -> name = "Zelda" )

AssertEquality eve.IsSome __
AssertEquality zelda.IsSome __

[<Koan>]
let ChoosingItemsFromAList() =
let numbers = [ 1; 2; 3; ]

// choose takes a function that transforms the input into an option
// And filters out the results that are None.
let positiveNumbers =
numbers
|> List.choose someIfPositive

AssertEquality positiveNumbers [ __ ]

//You can also use the "id" function on types of 'a option list
//"id" will tell choose only to return just those that are "Some"
let optionNames = [ None; Some "Alice"; None; ]

let namesWithValue =
optionNames
|> List.choose id

//Notice the type of actual result is 'string list', where as optionNumbers is 'string option list'
AssertEquality namesWithValue [ __ ]

[<Koan>]
let PickingItemsFromAList() =
let numbers = [ 5..10 ]

//Pick is similar to choose, but returns the first element, or throwns an exception if are no
//items that return "Some" (a bit like find does)
let firstEvenPositive =
numbers
|> List.pick someIfPositive

AssertEquality firstEvenPositive __

//As with choose, you can also use the "id" function on types of 'a option list
//to return just those that are "Some"
let optionNames = [ None; Some "Alice"; None; Some "Bob"; ]

let firstNameWithValue =
optionNames
|> List.pick id

AssertEquality firstNameWithValue __

//There is also a tryPick which works like tryFind, returning "None" instead of throwing an exception.
23 changes: 19 additions & 4 deletions FSharpKoans/FSharpKoans.fsproj
Expand Up @@ -14,6 +14,8 @@
</TargetFrameworkProfile>
<Name>FSharpKoans</Name>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<TargetFSharpCoreVersion>4.3.0.0</TargetFSharpCoreVersion>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
Expand All @@ -37,9 +39,19 @@
<PlatformTarget>x86</PlatformTarget>
<DocumentationFile>bin\Release\FSharpKoans1.XML</DocumentationFile>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')" />
<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="(!Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')) And (Exists('$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets'))" />
<Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="(!Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')) And (!Exists('$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets')) And (Exists('$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets'))" />
<Choose>
<When Condition="'$(VisualStudioVersion)' == '11.0'">
<PropertyGroup>
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
<PropertyGroup>
<PreBuildEvent />
</PropertyGroup>
Expand All @@ -64,14 +76,17 @@
<Compile Include="AboutDiscriminatedUnions.fs" />
<Compile Include="AboutModules.fs" />
<Compile Include="AboutClasses.fs" />
<Compile Include="AboutFiltering.fs" />
<Compile Include="PathToEnlightenment.fs" />
<None Include="App.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="FSharp.Core" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
Expand Down