Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Funcky.Test/Extensions/EnumerableExtensions/Flatten.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Funcky.Test.Extensions.EnumerableExtensions;

public sealed class Flatten
{
[Fact]
public void FlattenFlatsIEnumerable()
{
var elements = new List<int> { 1, 2, 3 };
Assert.Equal(elements, new List<IEnumerable<int>> { elements }.Flatten());
}
}
22 changes: 22 additions & 0 deletions Funcky.Test/Monads/EitherTest.Flatten.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Funcky.Test.Monads;

public sealed partial class EitherTest
{
[Fact]
public void FlattenLeftIsLeft()
{
Assert.Equal("test", FunctionalAssert.Left(Either<string, Either<string, int>>.Left("test").Flatten()));
}

[Fact]
public void FlattenRightLeftIsLeft()
{
Assert.Equal("test", FunctionalAssert.Left(Either<string, Either<string, int>>.Right(Either<string, int>.Left("test")).Flatten()));
}

[Fact]
public void FlattenRightRightIsRight()
{
FunctionalAssert.Right(4711, Either<string, Either<string, int>>.Right(Either<string, int>.Right(4711)).Flatten());
}
}
12 changes: 12 additions & 0 deletions Funcky.Test/Monads/LazyTest.Flatten.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using FsCheck;
using Funcky.FsCheck;
using Funcky.Test.TestUtils;

namespace Funcky.Test.Monads;

public sealed partial class LazyTest
{
[FunckyProperty]
public Property FlattenLazyLazyIsLazy(Lazy<string> input)
=> CheckAssert.Equal(Lazy.Return(input).Flatten(), input);
}
22 changes: 22 additions & 0 deletions Funcky.Test/Monads/OptionTest.Flatten.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Funcky.Test.Monads;

public sealed partial class OptionTest
{
[Fact]
public void FlattenNoneIsNone()
{
FunctionalAssert.None(Option<Option<int>>.None.Flatten());
}

[Fact]
public void FlattenSomeNoneIsNone()
{
FunctionalAssert.None(Option.Some(Option<int>.None).Flatten());
}

[Fact]
public void FlattenSomeSomeIsSome()
{
FunctionalAssert.Some(4711, Option.Some(Option.Some(4711)).Flatten());
}
}
12 changes: 12 additions & 0 deletions Funcky.Test/Monads/ReaderTest.Flatten.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using FsCheck;
using Funcky.FsCheck;
using Funcky.Test.TestUtils;

namespace Funcky.Test.Monads;

public sealed partial class ReaderTest
{
[FunckyProperty]
public Property FlattenReaderReaderIsReader(string environment, Reader<string, string> input)
=> CheckAssert.Equal(input, Reader<string>.Return(input).Flatten(), environment);
}
22 changes: 22 additions & 0 deletions Funcky.Test/Monads/ResultTest.Flatten.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Funcky.Test.Monads;

public sealed partial class ResultTest
{
[Fact]
public void FlattenErrorIsError()
{
FunctionalAssert.Error(Result<Result<int>>.Error(new Exception()).Flatten());
}

[Fact]
public void FlattenOkErrorIsError()
{
FunctionalAssert.Error(Result.Ok(Result<int>.Error(new Exception())).Flatten());
}

[Fact]
public void FlattenOkOkIsOk()
{
FunctionalAssert.Ok(4711, Result.Ok(Result.Ok(4711)).Flatten());
}
}
7 changes: 7 additions & 0 deletions Funcky/Extensions/EnumerableExtensions/Flatten.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Funcky.Extensions;

public static partial class EnumerableExtensions
{
public static IEnumerable<T> Flatten<T>(this IEnumerable<IEnumerable<T>> enumerable)
=> enumerable.SelectMany(Identity);
}
5 changes: 5 additions & 0 deletions Funcky/Monads/Either/EitherExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ namespace Funcky.Monads;

public static partial class EitherExtensions
{
public static Either<TLeft, TRight> Flatten<TLeft, TRight>(this Either<TLeft, Either<TLeft, TRight>> either)
where TLeft : notnull
where TRight : notnull
=> either.SelectMany(Identity);

/// <summary>Returns the left value or <see cref="Option{TItem}.None()"/> if the <paramref name="either"/> is a right value.</summary>
[Pure]
public static Option<TLeft> LeftOrNone<TLeft, TRight>(this Either<TLeft, TRight> either)
Expand Down
10 changes: 10 additions & 0 deletions Funcky/Monads/Lazy/LazyExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Diagnostics.CodeAnalysis;
using static System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes;

namespace Funcky.Monads;

public static partial class LazyExtensions
{
public static Lazy<T> Flatten<[DynamicallyAccessedMembers(PublicParameterlessConstructor)] T>(this Lazy<Lazy<T>> lazy)
=> Lazy.FromFunc(() => lazy.Value.Value);
}
4 changes: 4 additions & 0 deletions Funcky/Monads/Option/OptionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ namespace Funcky.Monads;

public static partial class OptionExtensions
{
public static Option<T> Flatten<T>(this Option<Option<T>> option)
where T : notnull
=> option.SelectMany(Identity);

public static Either<TLeft, TRight> ToEither<TLeft, TRight>(this Option<TRight> option, TLeft left)
where TLeft : notnull
where TRight : notnull
Expand Down
9 changes: 9 additions & 0 deletions Funcky/Monads/Reader/ReaderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Funcky.Monads;

public static partial class ReaderExtensions
{
public static Reader<TEnvironment, TItem> Flatten<TEnvironment, TItem>(this Reader<TEnvironment, Reader<TEnvironment, TItem>> reader)
where TEnvironment : notnull
where TItem : notnull
=> reader.SelectMany(Identity);
}
2 changes: 1 addition & 1 deletion Funcky/Monads/Result/ResultExtensions.Traversable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Funcky.Monads;

public static class ResultExtensions
public static partial class ResultExtensions
{
[Pure]
public static Either<TLeft, Result<TRight>> Traverse<TValidResult, TLeft, TRight>(
Expand Down
8 changes: 8 additions & 0 deletions Funcky/Monads/Result/ResultExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Funcky.Monads;

public static partial class ResultExtensions
{
public static Result<T> Flatten<T>(this Result<Result<T>> result)
where T : notnull
=> result.SelectMany(Identity);
}
6 changes: 6 additions & 0 deletions Funcky/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ static Funcky.Extensions.EnumerableExtensions.ElementAtOrNone<TSource>(this Syst
static Funcky.Extensions.EnumerableExtensions.ExclusiveScan<TSource, TAccumulate>(this System.Collections.Generic.IEnumerable<TSource>! source, TAccumulate seed, System.Func<TAccumulate, TSource, TAccumulate>! accumulator) -> System.Collections.Generic.IEnumerable<TAccumulate>!
static Funcky.Extensions.EnumerableExtensions.FirstOrNone<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source) -> Funcky.Monads.Option<TSource>
static Funcky.Extensions.EnumerableExtensions.FirstOrNone<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source, System.Func<TSource, bool>! predicate) -> Funcky.Monads.Option<TSource>
static Funcky.Extensions.EnumerableExtensions.Flatten<T>(this System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<T>!>! enumerable) -> System.Collections.Generic.IEnumerable<T>!
static Funcky.Extensions.EnumerableExtensions.ForEach<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source, System.Action<TSource>! action) -> Funcky.Unit
static Funcky.Extensions.EnumerableExtensions.ForEach<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source, System.Func<TSource, Funcky.Unit>! action) -> Funcky.Unit
static Funcky.Extensions.EnumerableExtensions.GetNonEnumeratedCountOrNone<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source) -> Funcky.Monads.Option<int>
Expand Down Expand Up @@ -758,11 +759,13 @@ static Funcky.Monads.EitherExtensions.Traverse<TLeft, TRight, T>(this Funcky.Mon
static Funcky.Monads.EitherExtensions.Traverse<TLeft, TRight, TEnvironment, TResult>(this Funcky.Monads.Either<TLeft, TRight> either, System.Func<TRight, Funcky.Monads.Reader<TEnvironment, TResult>!>! selector) -> Funcky.Monads.Reader<TEnvironment, Funcky.Monads.Either<TLeft, TResult>>!
static Funcky.Monads.EitherExtensions.Traverse<TLeft, TRight, TItem>(this Funcky.Monads.Either<TLeft, TRight> either, System.Func<TRight, Funcky.Monads.Option<TItem>>! selector) -> Funcky.Monads.Option<Funcky.Monads.Either<TLeft, TItem>>
static Funcky.Monads.EitherExtensions.Traverse<TLeft, TRight, TValidResult>(this Funcky.Monads.Either<TLeft, TRight> either, System.Func<TRight, Funcky.Monads.Result<TValidResult>>! selector) -> Funcky.Monads.Result<Funcky.Monads.Either<TLeft, TValidResult>>
static Funcky.Monads.EitherExtensions.Flatten<TLeft, TRight>(this Funcky.Monads.Either<TLeft, Funcky.Monads.Either<TLeft, TRight>> either) -> Funcky.Monads.Either<TLeft, TRight>
static Funcky.Monads.Lazy.FromFunc<T>(System.Func<T>! valueFactory) -> System.Lazy<T>!
static Funcky.Monads.Lazy.Return<T>(T value) -> System.Lazy<T>!
static Funcky.Monads.LazyExtensions.Select<T, TResult>(this System.Lazy<T>! lazy, System.Func<T, TResult>! selector) -> System.Lazy<TResult>!
static Funcky.Monads.LazyExtensions.SelectMany<T, TLazy, TResult>(this System.Lazy<T>! lazy, System.Func<T, System.Lazy<TLazy>!>! selector, System.Func<T, TLazy, TResult>! resultSelector) -> System.Lazy<TResult>!
static Funcky.Monads.LazyExtensions.SelectMany<T, TResult>(this System.Lazy<T>! lazy, System.Func<T, System.Lazy<TResult>!>! selector) -> System.Lazy<TResult>!
static Funcky.Monads.LazyExtensions.Flatten<T>(this System.Lazy<System.Lazy<T>!>! lazy) -> System.Lazy<T>!
static Funcky.Monads.Option.FromBoolean(bool boolean) -> Funcky.Monads.Option<Funcky.Unit>
static Funcky.Monads.Option.FromBoolean<TItem>(bool boolean, System.Func<TItem>! selector) -> Funcky.Monads.Option<TItem>
static Funcky.Monads.Option.FromBoolean<TItem>(bool boolean, TItem item) -> Funcky.Monads.Option<TItem>
Expand Down Expand Up @@ -797,12 +800,14 @@ static Funcky.Monads.OptionExtensions.Traverse<TItem, T>(this Funcky.Monads.Opti
static Funcky.Monads.OptionExtensions.Traverse<TItem, TEnvironment, TResult>(this Funcky.Monads.Option<TItem> option, System.Func<TItem, Funcky.Monads.Reader<TEnvironment, TResult>!>! selector) -> Funcky.Monads.Reader<TEnvironment, Funcky.Monads.Option<TResult>>!
static Funcky.Monads.OptionExtensions.Traverse<TItem, TLeft, TRight>(this Funcky.Monads.Option<TItem> option, System.Func<TItem, Funcky.Monads.Either<TLeft, TRight>>! selector) -> Funcky.Monads.Either<TLeft, Funcky.Monads.Option<TRight>>
static Funcky.Monads.OptionExtensions.Traverse<TItem, TValidResult>(this Funcky.Monads.Option<TItem> option, System.Func<TItem, Funcky.Monads.Result<TValidResult>>! selector) -> Funcky.Monads.Result<Funcky.Monads.Option<TValidResult>>
static Funcky.Monads.OptionExtensions.Flatten<T>(this Funcky.Monads.Option<Funcky.Monads.Option<T>> option) -> Funcky.Monads.Option<T>
static Funcky.Monads.Reader<TEnvironment>.FromAction(System.Action<TEnvironment>! action) -> Funcky.Monads.Reader<TEnvironment, Funcky.Unit>!
static Funcky.Monads.Reader<TEnvironment>.FromFunc<TResult>(System.Func<TEnvironment, TResult>! function) -> Funcky.Monads.Reader<TEnvironment, TResult>!
static Funcky.Monads.Reader<TEnvironment>.Return<TResult>(TResult value) -> Funcky.Monads.Reader<TEnvironment, TResult>!
static Funcky.Monads.ReaderExtensions.Select<TEnvironment, TSource, TResult>(this Funcky.Monads.Reader<TEnvironment, TSource>! source, System.Func<TSource, TResult>! selector) -> Funcky.Monads.Reader<TEnvironment, TResult>!
static Funcky.Monads.ReaderExtensions.SelectMany<TEnvironment, TSource, TReader, TResult>(this Funcky.Monads.Reader<TEnvironment, TSource>! source, System.Func<TSource, Funcky.Monads.Reader<TEnvironment, TReader>!>! selector, System.Func<TSource, TReader, TResult>! resultSelector) -> Funcky.Monads.Reader<TEnvironment, TResult>!
static Funcky.Monads.ReaderExtensions.SelectMany<TEnvironment, TSource, TResult>(this Funcky.Monads.Reader<TEnvironment, TSource>! source, System.Func<TSource, Funcky.Monads.Reader<TEnvironment, TResult>!>! selector) -> Funcky.Monads.Reader<TEnvironment, TResult>!
static Funcky.Monads.ReaderExtensions.Flatten<TEnvironment, TItem>(this Funcky.Monads.Reader<TEnvironment, Funcky.Monads.Reader<TEnvironment, TItem>!>! reader) -> Funcky.Monads.Reader<TEnvironment, TItem>!
static Funcky.Monads.Result.Ok<TValidResult>(TValidResult result) -> Funcky.Monads.Result<TValidResult>
static Funcky.Monads.Result.Return<TValidResult>(TValidResult result) -> Funcky.Monads.Result<TValidResult>
static Funcky.Monads.Result<TValidResult>.Error(System.Exception! exception) -> Funcky.Monads.Result<TValidResult>
Expand All @@ -819,6 +824,7 @@ static Funcky.Monads.ResultExtensions.Traverse<TValidResult, T>(this Funcky.Mona
static Funcky.Monads.ResultExtensions.Traverse<TValidResult, TEnvironment, TResult>(this Funcky.Monads.Result<TValidResult> result, System.Func<TValidResult, Funcky.Monads.Reader<TEnvironment, TResult>!>! selector) -> Funcky.Monads.Reader<TEnvironment, Funcky.Monads.Result<TResult>>!
static Funcky.Monads.ResultExtensions.Traverse<TValidResult, TItem>(this Funcky.Monads.Result<TValidResult> result, System.Func<TValidResult, Funcky.Monads.Option<TItem>>! selector) -> Funcky.Monads.Option<Funcky.Monads.Result<TItem>>
static Funcky.Monads.ResultExtensions.Traverse<TValidResult, TLeft, TRight>(this Funcky.Monads.Result<TValidResult> result, System.Func<TValidResult, Funcky.Monads.Either<TLeft, TRight>>! selector) -> Funcky.Monads.Either<TLeft, Funcky.Monads.Result<TRight>>
static Funcky.Monads.ResultExtensions.Flatten<T>(this Funcky.Monads.Result<Funcky.Monads.Result<T>> result) -> Funcky.Monads.Result<T>
static Funcky.Sequence.Concat<TSource>(params System.Collections.Generic.IEnumerable<TSource>![]! sources) -> System.Collections.Generic.IEnumerable<TSource>!
static Funcky.Sequence.Concat<TSource>(System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<TSource>!>! sources) -> System.Collections.Generic.IEnumerable<TSource>!
static Funcky.Sequence.Cycle<TResult>(TResult element) -> System.Collections.Generic.IEnumerable<TResult>!
Expand Down