From 3690776d846de5e1440a757faf1e2ee09516e73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20J=C3=A1nos=20Csillik?= Date: Wed, 28 May 2025 23:06:53 +0200 Subject: [PATCH 1/5] Add Flatten to monads --- Funcky.Test/Monads/EitherTest.Flatten.cs | 22 +++++++++++++++++++ Funcky.Test/Monads/IEnumerableTest.Flatten.cs | 11 ++++++++++ Funcky.Test/Monads/LazyTest.Flatten.cs | 12 ++++++++++ Funcky.Test/Monads/OptionTest.Flatten.cs | 22 +++++++++++++++++++ Funcky.Test/Monads/ReaderTest.Flatten.cs | 12 ++++++++++ Funcky.Test/Monads/ResultTest.Flatten.cs | 22 +++++++++++++++++++ Funcky/Monads/Either/EitherExtensions.cs | 5 +++++ .../IEnumerable/IEnumerableExtensions.cs | 8 +++++++ Funcky/Monads/Lazy/LazyExtensions.cs | 10 +++++++++ Funcky/Monads/Option/OptionExtensions.cs | 4 ++++ Funcky/Monads/Reader/ReaderExtensions.cs | 9 ++++++++ .../Result/ResultExtensions.Traversable.cs | 2 +- Funcky/Monads/Result/ResultExtensions.cs | 8 +++++++ Funcky/PublicAPI.Shipped.txt | 7 ++++++ 14 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 Funcky.Test/Monads/EitherTest.Flatten.cs create mode 100644 Funcky.Test/Monads/IEnumerableTest.Flatten.cs create mode 100644 Funcky.Test/Monads/LazyTest.Flatten.cs create mode 100644 Funcky.Test/Monads/OptionTest.Flatten.cs create mode 100644 Funcky.Test/Monads/ReaderTest.Flatten.cs create mode 100644 Funcky.Test/Monads/ResultTest.Flatten.cs create mode 100644 Funcky/Monads/IEnumerable/IEnumerableExtensions.cs create mode 100644 Funcky/Monads/Lazy/LazyExtensions.cs create mode 100644 Funcky/Monads/Reader/ReaderExtensions.cs create mode 100644 Funcky/Monads/Result/ResultExtensions.cs diff --git a/Funcky.Test/Monads/EitherTest.Flatten.cs b/Funcky.Test/Monads/EitherTest.Flatten.cs new file mode 100644 index 000000000..f3ac9e6e7 --- /dev/null +++ b/Funcky.Test/Monads/EitherTest.Flatten.cs @@ -0,0 +1,22 @@ +namespace Funcky.Test.Monads; + +public sealed partial class EitherTest +{ + [Fact] + public void FlattenLeftIsLeft() + { + Assert.Equal("test", FunctionalAssert.Left(Either>.Left("test").Flatten())); + } + + [Fact] + public void FlattenRightLeftIsLeft() + { + Assert.Equal("test", FunctionalAssert.Left(Either>.Right(Either.Left("test")).Flatten())); + } + + [Fact] + public void FlattenRightRightIsRight() + { + FunctionalAssert.Right(4711, Either>.Right(Either.Right(4711)).Flatten()); + } +} diff --git a/Funcky.Test/Monads/IEnumerableTest.Flatten.cs b/Funcky.Test/Monads/IEnumerableTest.Flatten.cs new file mode 100644 index 000000000..8f0586843 --- /dev/null +++ b/Funcky.Test/Monads/IEnumerableTest.Flatten.cs @@ -0,0 +1,11 @@ +namespace Funcky.Test.Monads; + +public sealed partial class IEnumerableTest +{ + [Fact] + public void FlattenFlatsIEnumerable() + { + var elements = new List { 1, 2, 3 }; + Assert.Equal(elements, new List> { elements }.Flatten()); + } +} diff --git a/Funcky.Test/Monads/LazyTest.Flatten.cs b/Funcky.Test/Monads/LazyTest.Flatten.cs new file mode 100644 index 000000000..4842c099b --- /dev/null +++ b/Funcky.Test/Monads/LazyTest.Flatten.cs @@ -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 input) + => CheckAssert.Equal(Lazy.Return(input).Flatten(), input); +} diff --git a/Funcky.Test/Monads/OptionTest.Flatten.cs b/Funcky.Test/Monads/OptionTest.Flatten.cs new file mode 100644 index 000000000..d2d3a2be0 --- /dev/null +++ b/Funcky.Test/Monads/OptionTest.Flatten.cs @@ -0,0 +1,22 @@ +namespace Funcky.Test.Monads; + +public sealed partial class OptionTest +{ + [Fact] + public void FlattenNoneIsNone() + { + FunctionalAssert.None(Option>.None.Flatten()); + } + + [Fact] + public void FlattenSomeNoneIsNone() + { + FunctionalAssert.None(Option.Some(Option.None).Flatten()); + } + + [Fact] + public void FlattenSomeSomeIsSome() + { + FunctionalAssert.Some(4711, Option.Some(Option.Some(4711)).Flatten()); + } +} diff --git a/Funcky.Test/Monads/ReaderTest.Flatten.cs b/Funcky.Test/Monads/ReaderTest.Flatten.cs new file mode 100644 index 000000000..2f8f7fa1f --- /dev/null +++ b/Funcky.Test/Monads/ReaderTest.Flatten.cs @@ -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 input) + => CheckAssert.Equal(input, Reader.Return(input).Flatten(), environment); +} diff --git a/Funcky.Test/Monads/ResultTest.Flatten.cs b/Funcky.Test/Monads/ResultTest.Flatten.cs new file mode 100644 index 000000000..0946962e5 --- /dev/null +++ b/Funcky.Test/Monads/ResultTest.Flatten.cs @@ -0,0 +1,22 @@ +namespace Funcky.Test.Monads; + +public sealed partial class ResultTest +{ + [Fact] + public void FlattenErrorIsError() + { + FunctionalAssert.Error(Result>.Error(new Exception()).Flatten()); + } + + [Fact] + public void FlattenSomeNoneIsNone() + { + FunctionalAssert.Error(Result.Ok(Result.Error(new Exception())).Flatten()); + } + + [Fact] + public void FlattenSomeSomeIsSome() + { + FunctionalAssert.Ok(4711, Result.Ok(Result.Ok(4711)).Flatten()); + } +} diff --git a/Funcky/Monads/Either/EitherExtensions.cs b/Funcky/Monads/Either/EitherExtensions.cs index 126c2e119..55b13ad2f 100644 --- a/Funcky/Monads/Either/EitherExtensions.cs +++ b/Funcky/Monads/Either/EitherExtensions.cs @@ -2,6 +2,11 @@ namespace Funcky.Monads; public static partial class EitherExtensions { + public static Either Flatten(this Either> either) + where TLeft : notnull + where TRight : notnull + => either.SelectMany(Identity); + /// Returns the left value or if the is a right value. [Pure] public static Option LeftOrNone(this Either either) diff --git a/Funcky/Monads/IEnumerable/IEnumerableExtensions.cs b/Funcky/Monads/IEnumerable/IEnumerableExtensions.cs new file mode 100644 index 000000000..213e2f6b7 --- /dev/null +++ b/Funcky/Monads/IEnumerable/IEnumerableExtensions.cs @@ -0,0 +1,8 @@ +namespace Funcky.Monads; + +public static partial class IEnumerableExtensions +{ + public static IEnumerable Flatten(this IEnumerable> enumerable) + where T : notnull + => enumerable.SelectMany(Identity); +} diff --git a/Funcky/Monads/Lazy/LazyExtensions.cs b/Funcky/Monads/Lazy/LazyExtensions.cs new file mode 100644 index 000000000..a30efe080 --- /dev/null +++ b/Funcky/Monads/Lazy/LazyExtensions.cs @@ -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 Flatten<[DynamicallyAccessedMembers(PublicParameterlessConstructor)] T>(this Lazy> lazy) + => new Lazy(() => lazy.Value.Value); +} diff --git a/Funcky/Monads/Option/OptionExtensions.cs b/Funcky/Monads/Option/OptionExtensions.cs index 0e516c645..d6f3bc91a 100644 --- a/Funcky/Monads/Option/OptionExtensions.cs +++ b/Funcky/Monads/Option/OptionExtensions.cs @@ -4,6 +4,10 @@ namespace Funcky.Monads; public static partial class OptionExtensions { + public static Option Flatten(this Option> option) + where T : notnull + => option.SelectMany(Identity); + public static Either ToEither(this Option option, TLeft left) where TLeft : notnull where TRight : notnull diff --git a/Funcky/Monads/Reader/ReaderExtensions.cs b/Funcky/Monads/Reader/ReaderExtensions.cs new file mode 100644 index 000000000..2b3685a08 --- /dev/null +++ b/Funcky/Monads/Reader/ReaderExtensions.cs @@ -0,0 +1,9 @@ +namespace Funcky.Monads; + +public static partial class ReaderExtensions +{ + public static Reader Flatten(this Reader> reader) + where TEnvironment : notnull + where TItem : notnull + => reader.SelectMany(Identity); +} diff --git a/Funcky/Monads/Result/ResultExtensions.Traversable.cs b/Funcky/Monads/Result/ResultExtensions.Traversable.cs index 8c21d6ff5..70eed4b4d 100644 --- a/Funcky/Monads/Result/ResultExtensions.Traversable.cs +++ b/Funcky/Monads/Result/ResultExtensions.Traversable.cs @@ -3,7 +3,7 @@ namespace Funcky.Monads; -public static class ResultExtensions +public static partial class ResultExtensions { [Pure] public static Either> Traverse( diff --git a/Funcky/Monads/Result/ResultExtensions.cs b/Funcky/Monads/Result/ResultExtensions.cs new file mode 100644 index 000000000..b929c30c5 --- /dev/null +++ b/Funcky/Monads/Result/ResultExtensions.cs @@ -0,0 +1,8 @@ +namespace Funcky.Monads; + +public static partial class ResultExtensions +{ + public static Result Flatten(this Result> result) + where T : notnull + => result.SelectMany(Identity); +} diff --git a/Funcky/PublicAPI.Shipped.txt b/Funcky/PublicAPI.Shipped.txt index 2650399f2..46bd6f3ff 100644 --- a/Funcky/PublicAPI.Shipped.txt +++ b/Funcky/PublicAPI.Shipped.txt @@ -123,6 +123,7 @@ Funcky.Monads.OptionEqualityComparer Funcky.Monads.OptionExtensions Funcky.Monads.OptionJsonConverter Funcky.Monads.OptionJsonConverter.OptionJsonConverter() -> void +Funcky.Monads.IEnumerableExtensions Funcky.Monads.Reader Funcky.Monads.Reader Funcky.Monads.ReaderExtensions @@ -758,11 +759,13 @@ static Funcky.Monads.EitherExtensions.Traverse(this Funcky.Mon static Funcky.Monads.EitherExtensions.Traverse(this Funcky.Monads.Either either, System.Func!>! selector) -> Funcky.Monads.Reader>! static Funcky.Monads.EitherExtensions.Traverse(this Funcky.Monads.Either either, System.Func>! selector) -> Funcky.Monads.Option> static Funcky.Monads.EitherExtensions.Traverse(this Funcky.Monads.Either either, System.Func>! selector) -> Funcky.Monads.Result> +static Funcky.Monads.EitherExtensions.Flatten(this Funcky.Monads.Either> either) -> Funcky.Monads.Either static Funcky.Monads.Lazy.FromFunc(System.Func! valueFactory) -> System.Lazy! static Funcky.Monads.Lazy.Return(T value) -> System.Lazy! static Funcky.Monads.LazyExtensions.Select(this System.Lazy! lazy, System.Func! selector) -> System.Lazy! static Funcky.Monads.LazyExtensions.SelectMany(this System.Lazy! lazy, System.Func!>! selector, System.Func! resultSelector) -> System.Lazy! static Funcky.Monads.LazyExtensions.SelectMany(this System.Lazy! lazy, System.Func!>! selector) -> System.Lazy! +static Funcky.Monads.LazyExtensions.Flatten(this System.Lazy!>! lazy) -> System.Lazy! static Funcky.Monads.Option.FromBoolean(bool boolean) -> Funcky.Monads.Option static Funcky.Monads.Option.FromBoolean(bool boolean, System.Func! selector) -> Funcky.Monads.Option static Funcky.Monads.Option.FromBoolean(bool boolean, TItem item) -> Funcky.Monads.Option @@ -797,12 +800,15 @@ static Funcky.Monads.OptionExtensions.Traverse(this Funcky.Monads.Opti static Funcky.Monads.OptionExtensions.Traverse(this Funcky.Monads.Option option, System.Func!>! selector) -> Funcky.Monads.Reader>! static Funcky.Monads.OptionExtensions.Traverse(this Funcky.Monads.Option option, System.Func>! selector) -> Funcky.Monads.Either> static Funcky.Monads.OptionExtensions.Traverse(this Funcky.Monads.Option option, System.Func>! selector) -> Funcky.Monads.Result> +static Funcky.Monads.OptionExtensions.Flatten(this Funcky.Monads.Option> option) -> Funcky.Monads.Option +static Funcky.Monads.IEnumerableExtensions.Flatten(this System.Collections.Generic.IEnumerable!>! enumerable) -> System.Collections.Generic.IEnumerable! static Funcky.Monads.Reader.FromAction(System.Action! action) -> Funcky.Monads.Reader! static Funcky.Monads.Reader.FromFunc(System.Func! function) -> Funcky.Monads.Reader! static Funcky.Monads.Reader.Return(TResult value) -> Funcky.Monads.Reader! static Funcky.Monads.ReaderExtensions.Select(this Funcky.Monads.Reader! source, System.Func! selector) -> Funcky.Monads.Reader! static Funcky.Monads.ReaderExtensions.SelectMany(this Funcky.Monads.Reader! source, System.Func!>! selector, System.Func! resultSelector) -> Funcky.Monads.Reader! static Funcky.Monads.ReaderExtensions.SelectMany(this Funcky.Monads.Reader! source, System.Func!>! selector) -> Funcky.Monads.Reader! +static Funcky.Monads.ReaderExtensions.Flatten(this Funcky.Monads.Reader!>! reader) -> Funcky.Monads.Reader! static Funcky.Monads.Result.Ok(TValidResult result) -> Funcky.Monads.Result static Funcky.Monads.Result.Return(TValidResult result) -> Funcky.Monads.Result static Funcky.Monads.Result.Error(System.Exception! exception) -> Funcky.Monads.Result @@ -819,6 +825,7 @@ static Funcky.Monads.ResultExtensions.Traverse(this Funcky.Mona static Funcky.Monads.ResultExtensions.Traverse(this Funcky.Monads.Result result, System.Func!>! selector) -> Funcky.Monads.Reader>! static Funcky.Monads.ResultExtensions.Traverse(this Funcky.Monads.Result result, System.Func>! selector) -> Funcky.Monads.Option> static Funcky.Monads.ResultExtensions.Traverse(this Funcky.Monads.Result result, System.Func>! selector) -> Funcky.Monads.Either> +static Funcky.Monads.ResultExtensions.Flatten(this Funcky.Monads.Result> result) -> Funcky.Monads.Result static Funcky.Sequence.Concat(params System.Collections.Generic.IEnumerable![]! sources) -> System.Collections.Generic.IEnumerable! static Funcky.Sequence.Concat(System.Collections.Generic.IEnumerable!>! sources) -> System.Collections.Generic.IEnumerable! static Funcky.Sequence.Cycle(TResult element) -> System.Collections.Generic.IEnumerable! From ca7c88a06c070230a4e9300b48fa04ff896ca0ea Mon Sep 17 00:00:00 2001 From: csillikd-messerli <68327616+csillikd-messerli@users.noreply.github.com> Date: Wed, 4 Jun 2025 13:32:28 +0200 Subject: [PATCH 2/5] Update Funcky.Test/Monads/ResultTest.Flatten.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tau Gärtli --- Funcky.Test/Monads/ResultTest.Flatten.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Funcky.Test/Monads/ResultTest.Flatten.cs b/Funcky.Test/Monads/ResultTest.Flatten.cs index 0946962e5..7e1a7f5c5 100644 --- a/Funcky.Test/Monads/ResultTest.Flatten.cs +++ b/Funcky.Test/Monads/ResultTest.Flatten.cs @@ -9,7 +9,7 @@ public void FlattenErrorIsError() } [Fact] - public void FlattenSomeNoneIsNone() + public void FlattenOkErrorIsError() { FunctionalAssert.Error(Result.Ok(Result.Error(new Exception())).Flatten()); } From 29d2a6029b60eda2257202c50121de895de7453f Mon Sep 17 00:00:00 2001 From: csillikd-messerli <68327616+csillikd-messerli@users.noreply.github.com> Date: Wed, 4 Jun 2025 13:32:34 +0200 Subject: [PATCH 3/5] Update Funcky.Test/Monads/ResultTest.Flatten.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tau Gärtli --- Funcky.Test/Monads/ResultTest.Flatten.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Funcky.Test/Monads/ResultTest.Flatten.cs b/Funcky.Test/Monads/ResultTest.Flatten.cs index 7e1a7f5c5..aeb391b97 100644 --- a/Funcky.Test/Monads/ResultTest.Flatten.cs +++ b/Funcky.Test/Monads/ResultTest.Flatten.cs @@ -15,7 +15,7 @@ public void FlattenOkErrorIsError() } [Fact] - public void FlattenSomeSomeIsSome() + public void FlattenOkOkIsOk() { FunctionalAssert.Ok(4711, Result.Ok(Result.Ok(4711)).Flatten()); } From 9f13947fc0834d12a059dce3c48e6dd9e8d81e0e Mon Sep 17 00:00:00 2001 From: csillikd-messerli <68327616+csillikd-messerli@users.noreply.github.com> Date: Wed, 4 Jun 2025 13:32:46 +0200 Subject: [PATCH 4/5] Update Funcky/Monads/Lazy/LazyExtensions.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tau Gärtli --- Funcky/Monads/Lazy/LazyExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Funcky/Monads/Lazy/LazyExtensions.cs b/Funcky/Monads/Lazy/LazyExtensions.cs index a30efe080..ffdfa59dd 100644 --- a/Funcky/Monads/Lazy/LazyExtensions.cs +++ b/Funcky/Monads/Lazy/LazyExtensions.cs @@ -6,5 +6,5 @@ namespace Funcky.Monads; public static partial class LazyExtensions { public static Lazy Flatten<[DynamicallyAccessedMembers(PublicParameterlessConstructor)] T>(this Lazy> lazy) - => new Lazy(() => lazy.Value.Value); + => Lazy.FromFunc(() => lazy.Value.Value); } From 1f19945f6d699ecc6479e4ef16c879bc682a41ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20J=C3=A1nos=20Csillik?= Date: Wed, 4 Jun 2025 13:41:34 +0200 Subject: [PATCH 5/5] Move IEnumerable.Flatten to the right place --- .../EnumerableExtensions/Flatten.cs} | 4 ++-- .../EnumerableExtensions/Flatten.cs} | 5 ++--- Funcky/PublicAPI.Shipped.txt | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-) rename Funcky.Test/{Monads/IEnumerableTest.Flatten.cs => Extensions/EnumerableExtensions/Flatten.cs} (70%) rename Funcky/{Monads/IEnumerable/IEnumerableExtensions.cs => Extensions/EnumerableExtensions/Flatten.cs} (57%) diff --git a/Funcky.Test/Monads/IEnumerableTest.Flatten.cs b/Funcky.Test/Extensions/EnumerableExtensions/Flatten.cs similarity index 70% rename from Funcky.Test/Monads/IEnumerableTest.Flatten.cs rename to Funcky.Test/Extensions/EnumerableExtensions/Flatten.cs index 8f0586843..11e902838 100644 --- a/Funcky.Test/Monads/IEnumerableTest.Flatten.cs +++ b/Funcky.Test/Extensions/EnumerableExtensions/Flatten.cs @@ -1,6 +1,6 @@ -namespace Funcky.Test.Monads; +namespace Funcky.Test.Extensions.EnumerableExtensions; -public sealed partial class IEnumerableTest +public sealed class Flatten { [Fact] public void FlattenFlatsIEnumerable() diff --git a/Funcky/Monads/IEnumerable/IEnumerableExtensions.cs b/Funcky/Extensions/EnumerableExtensions/Flatten.cs similarity index 57% rename from Funcky/Monads/IEnumerable/IEnumerableExtensions.cs rename to Funcky/Extensions/EnumerableExtensions/Flatten.cs index 213e2f6b7..c8b2b3463 100644 --- a/Funcky/Monads/IEnumerable/IEnumerableExtensions.cs +++ b/Funcky/Extensions/EnumerableExtensions/Flatten.cs @@ -1,8 +1,7 @@ -namespace Funcky.Monads; +namespace Funcky.Extensions; -public static partial class IEnumerableExtensions +public static partial class EnumerableExtensions { public static IEnumerable Flatten(this IEnumerable> enumerable) - where T : notnull => enumerable.SelectMany(Identity); } diff --git a/Funcky/PublicAPI.Shipped.txt b/Funcky/PublicAPI.Shipped.txt index 46bd6f3ff..c7b1e8bc0 100644 --- a/Funcky/PublicAPI.Shipped.txt +++ b/Funcky/PublicAPI.Shipped.txt @@ -123,7 +123,6 @@ Funcky.Monads.OptionEqualityComparer Funcky.Monads.OptionExtensions Funcky.Monads.OptionJsonConverter Funcky.Monads.OptionJsonConverter.OptionJsonConverter() -> void -Funcky.Monads.IEnumerableExtensions Funcky.Monads.Reader Funcky.Monads.Reader Funcky.Monads.ReaderExtensions @@ -263,6 +262,7 @@ static Funcky.Extensions.EnumerableExtensions.ElementAtOrNone(this Syst static Funcky.Extensions.EnumerableExtensions.ExclusiveScan(this System.Collections.Generic.IEnumerable! source, TAccumulate seed, System.Func! accumulator) -> System.Collections.Generic.IEnumerable! static Funcky.Extensions.EnumerableExtensions.FirstOrNone(this System.Collections.Generic.IEnumerable! source) -> Funcky.Monads.Option static Funcky.Extensions.EnumerableExtensions.FirstOrNone(this System.Collections.Generic.IEnumerable! source, System.Func! predicate) -> Funcky.Monads.Option +static Funcky.Extensions.EnumerableExtensions.Flatten(this System.Collections.Generic.IEnumerable!>! enumerable) -> System.Collections.Generic.IEnumerable! static Funcky.Extensions.EnumerableExtensions.ForEach(this System.Collections.Generic.IEnumerable! source, System.Action! action) -> Funcky.Unit static Funcky.Extensions.EnumerableExtensions.ForEach(this System.Collections.Generic.IEnumerable! source, System.Func! action) -> Funcky.Unit static Funcky.Extensions.EnumerableExtensions.GetNonEnumeratedCountOrNone(this System.Collections.Generic.IEnumerable! source) -> Funcky.Monads.Option @@ -801,7 +801,6 @@ static Funcky.Monads.OptionExtensions.Traverse(thi static Funcky.Monads.OptionExtensions.Traverse(this Funcky.Monads.Option option, System.Func>! selector) -> Funcky.Monads.Either> static Funcky.Monads.OptionExtensions.Traverse(this Funcky.Monads.Option option, System.Func>! selector) -> Funcky.Monads.Result> static Funcky.Monads.OptionExtensions.Flatten(this Funcky.Monads.Option> option) -> Funcky.Monads.Option -static Funcky.Monads.IEnumerableExtensions.Flatten(this System.Collections.Generic.IEnumerable!>! enumerable) -> System.Collections.Generic.IEnumerable! static Funcky.Monads.Reader.FromAction(System.Action! action) -> Funcky.Monads.Reader! static Funcky.Monads.Reader.FromFunc(System.Func! function) -> Funcky.Monads.Reader! static Funcky.Monads.Reader.Return(TResult value) -> Funcky.Monads.Reader!