Skip to content

Commit

Permalink
Issue #36 - started adding Match().ReduceTo() functionality.
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidArno committed Aug 3, 2017
1 parent 8f0c9c3 commit 37fd1eb
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/SuccincT/Functional/ConsEnumerable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ internal ConsEnumerable(IEnumerable<T> enumeration) =>
Next = EnumerationConsNode(enumeration)
};

internal ConsEnumerable(T element) =>
_node = new ConsNode<T>
{
State = StartNode,
Next = new ConsNode<T>
{
Value = element,
State = HasValue
}
};

private ConsEnumerable(IEnumerable<T> enumeration, T head) =>
_node = new ConsNode<T>
{
Expand Down
1 change: 1 addition & 0 deletions src/SuccincT/PatternMatchers/ConsActionMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ internal class ConsActionMatcher<T> : IConsActionMatcher<T>
public ConsActionMatcher(IEnumerable<T> collection) => _collection = collection;

public IConsFuncMatcher<T, TResult> To<TResult>() => new ConsFuncMatcher<T, TResult>(_collection);
public IReducerMatcher<T, TResult> ReduceTo<TResult>() => new ReducerMatcher<T, TResult>(_collection);
}
}
1 change: 1 addition & 0 deletions src/SuccincT/PatternMatchers/IConsActionMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
public interface IConsActionMatcher<T>
{
IConsFuncMatcher<T, TResult> To<TResult>();
IReducerMatcher<T, TResult> ReduceTo<TResult>();
}
}
15 changes: 15 additions & 0 deletions src/SuccincT/PatternMatchers/IReducerMatcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Collections.Generic;

namespace SuccincT.PatternMatchers
{
public interface IReducerMatcher<T, TResult>
{
IReducerNoneHandler<T, TResult> Empty();

IReducerSingleHandler<T, TResult> Single();

//IReducerRecursiveConsHandler<T, TResult> RecursiveCons();

IEnumerable<TResult> Result();
}
}
7 changes: 7 additions & 0 deletions src/SuccincT/PatternMatchers/IReducerNoneHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace SuccincT.PatternMatchers
{
public interface IReducerNoneHandler<T, TResult>
{
IReducerMatcher<T, TResult> Do(TResult doValue);
}
}
10 changes: 10 additions & 0 deletions src/SuccincT/PatternMatchers/IReducerSingleHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;

namespace SuccincT.PatternMatchers
{
public interface IReducerSingleHandler<T, TResult>
{
IReducerMatcher<T, TResult> Do(TResult doValue);
IReducerMatcher<T, TResult> Do(Func<T,TResult> doFunc);
}
}
53 changes: 53 additions & 0 deletions src/SuccincT/PatternMatchers/ReducerMatcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SuccincT.Functional;

namespace SuccincT.PatternMatchers
{
internal class ReducerMatcher<T, TResult> : IReducerMatcher<T, TResult>,
IReducerNoneHandler<T, TResult>,
IReducerSingleHandler<T, TResult>
{
private readonly IEnumerable<T> _collection;
private TResult _noneValue;
private List<Func<T, TResult>> _singleTestDos;

public ReducerMatcher(IEnumerable<T> collection)
{
_collection = collection;
_singleTestDos = new List<Func<T, TResult>>();
}

IReducerNoneHandler<T, TResult> IReducerMatcher<T, TResult>.Empty() => this;

IReducerSingleHandler<T, TResult> IReducerMatcher<T, TResult>.Single() => this;

IReducerMatcher<T, TResult> IReducerNoneHandler<T, TResult>.Do(TResult doValue)
{
_noneValue = doValue;
return this;
}

IReducerMatcher<T, TResult> IReducerSingleHandler<T, TResult>.Do(Func<T, TResult> doFunc)
{
_singleTestDos.Add(doFunc);
return this;
}

IReducerMatcher<T, TResult> IReducerSingleHandler<T, TResult>.Do(TResult doValue)
{
_singleTestDos.Add(_ => doValue);
return this;
}

IEnumerable<TResult> IReducerMatcher<T, TResult>.Result()
{
if (!_collection.Any())
{
return new ConsEnumerable<TResult>(_noneValue);
}
return new ConsEnumerable<TResult>(_singleTestDos[0](_collection.First()));
}
}
}
3 changes: 3 additions & 0 deletions src/SuccincT/PatternMatchers/SpecificTypeMatcherExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public static IMatcher<T1, T2, T3, T4> Match<T1, T2, T3, T4>(this ITupleMatchabl

public static IConsActionMatcher<T> Match<T>(this IEnumerable<T> collection) => new ConsActionMatcher<T>(collection);

public static IConsActionMatcher<T> Match<T>(this IList<T> collection) => new ConsActionMatcher<T>(collection);

public static IConsActionMatcher<T> Match<T>(this List<T> collection) => new ConsActionMatcher<T>(collection);

private static (T1, T2) AsTuple<T1, T2>(this Tuple<T1, T2> value) => (value.Item1, value.Item2);

Expand Down
1 change: 1 addition & 0 deletions src/SuccincT/SuccincT.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<RepositoryUrl>https://github.com/DavidArno/SuccincT</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageReleaseNotes>V3.0.0 re-introduces support for dotnet core, along with many other frameworks, by switching to being a .netstandard 1.0 library. In addition it brings C# 7 support with cons that now works via a deconstructor, pattern matching on value tuples and indexed enumerations. Please note it alos includes some breaking changes (thus the major version number increase). See the project site for details.</PackageReleaseNotes>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using SuccincT.Functional;
using SuccincT.PatternMatchers;

namespace SuccincTTests.SuccincT.PatternMatchers
{
[TestFixture]
public class ReducerMatcherTests
{
[Test]
public void EmptyList_ResultsInOneElementEnumerationWhenEmptyClauseUsed()
{
var list = new List<int>();
var result = list.Match().ReduceTo<(int, int)>()
.Empty().Do((0, 0))
.Result();

var consResult = result.ToConsEnumerable();
Assert.AreEqual(1, consResult.Count());
var (head, _) = consResult;
Assert.AreEqual((0, 0), head);
}

[Test]
public void SingleList_ResultsInOneElementEnumerationWhenValueSingleClauseUsed()
{
var list = new List<int> { 1 };
var result = list.Match().ReduceTo<(int, int)>()
.Single().Do((0, 1))
.Result();

var consResult = result.ToConsEnumerable();
Assert.AreEqual(1, consResult.Count());
var (head, _) = consResult;
Assert.AreEqual((0, 1), head);
}

[Test]
public void SingleList_ResultsInOneElementEnumerationWhenFuncSingleClauseUsed()
{
var list = new List<int> { 1 };
var result = list.Match().ReduceTo<(int, int)>()
.Single().Do(x => (x, 0))
.Result();

var consResult = result.ToConsEnumerable();
Assert.AreEqual(1, consResult.Count());
var (head, _) = consResult;
Assert.AreEqual((1, 0), head);
}
}
}

0 comments on commit 37fd1eb

Please sign in to comment.