Releases: polyadic/funcky
Funcky 3.5.1 | Funcky.Async 1.4.1 | Funcky.Xunit 2.1.1 | Funcky.Analyzers 1.4.1
This is a patch release which fixes vulnerability warnings of (direct and transitive) dependencies.
What's Changed
Full Changelog: 3.5.0...3.5.1
Funcky 3.5.0 | Funcky.Async 1.4.0 | Funcky.Xunit 2.1.0 | Funcky.Analyzers 1.4.0
This update is mainly to update to .NET 9 but also has several smaller improvements.
.NET 9
Thanks to the new [OverloadResolutionPriority] attribute, we've been able finally fix
the ambiguous call errors when using DictionaryExtensions.GetValueOrNone:
Dictionary<string, string> favouriteFoods = new();
Option<int> tausFavouriteFood = favouriteFoods.GetValueOrNone("Tau");
// ^^^^^^^^^^^^^^
// This used to produce a `error CS0121: The call is ambiguous between ...` error
// and now simply works 🎉In good old fashion, we've also added new parse extensions:
ParseExtensions.ParseAssemblyNameInfoOrNoneParseExtensions.ParseTypeNameOrNone
Policy for EOL Target Frameworks
We've explicitly written down our policy for how we deal
with older / EOL target frameworks.
In short: EOL target frameworks are supported by Funcky until the next major version.
However, we may no longer test Funcky against those target frameworks, so we
can't guarantee that everything works smoothly.
New APIs
In Funcky 3.0 we've changed CycleRange and RepeatRange to return an IBuffer
to enable us to memoize the collection, preventing unnecessary enumeration. This however
is unpractical for uses where you want to cycle an already materialized collection.
This release adds two new methods to accommodate that use case:
CycleMaterialized and RepeatMaterialized.
For convenient downcasting of Option<T>, Result<T> and Either<TLeft, T> values, we've added a new
DownCast class:
Option<object> option = Option.Some("hello world");
Option<string> downcasted = DownCast<string>.From(option);Funcky.XUnit
Funcky.XUnit has been updated to the latest version (2.9.3) of xUnit.net.
Due to changes in xUnit we've had to change the exception type thrown by our FunctionalAssert methods
from AssertActualExpectedException to XunitException.
Funcky.Analyzers
The new analyzer rule λ1009 prevents you from accidentally default-instantiating
Either, Result and EitherOrBoth.
Funcky.Async
The PowerSet and WithPrevious extensions now correctly pass along the cancellation token.
Funcky 3.4.0 | Funcky.Async 1.3.0 | Funcky.XUnit 2.0.2
This update is mainly to update to .NET 8 but also has several smaller improvements.
Native AOT
Both Funcky and Funcky.Async have been annotated to be compatible with Native AOT.
The only exception is OptionJsonSerializer which is not compatible with Native AOT.
.NET 8
We use the new C#12 and .NET features in the code, and expose new features through our API.
- .NET 8 added new overloads to their
TryParseAPIs. These changes are reflected in Funcky'sParseOrNoneAPIs.ParseByteOrNoneoverloads withReadOnlySpan<byte>andstring?ParseSByteOrNoneoverloads withReadOnlySpan<byte>ParseSingleOrNoneoverloads withReadOnlySpan<byte>ParseDoubleOrNoneoverloads withReadOnlySpan<byte>ParseDecimalOrNoneoverloads withReadOnlySpan<byte>ParseInt16OrNoneoverloads withReadOnlySpan<byte>ParseInt32OrNoneoverloads withReadOnlySpan<byte>ParseInt64OrNoneoverloads withReadOnlySpan<byte>ParseUInt16OrNoneoverloads withReadOnlySpan<byte>ParseUInt32OrNoneoverloads withReadOnlySpan<byte>ParseUInt64OrNoneoverloads withReadOnlySpan<byte>ParseNumberOrNone<TNumber>overloadsParseOrNone<TParsable>overloads
String Extensions
We implemented a few of the IEnumerable extensions which are very useful on strings.
Chunkonstring.SlidingWindowonstring.
Monads
- Implemented
UpCastfor the mondsOption,Either,ResultandSystem.Lazy. - Implemented
InspectEmptyonIEnumerableandIAsyncEnumerable - Implemented
ToAsyncEnumerableextension onOption
IEnumerator
MoveNextOrNoneextension onIEnumerator<T>
Consistency
FindIndexOrNoneandFindLastIndexOrNoneextensions onList
What's Changed
- Add
MoveNextOrNoneextension forIEnumeratorby @bash in #739 - Add
ToAsyncEnumerableextension forOptionby @bash in #741 - Implemented Chunk and SlidingWindow on string by @FreeApophis in #744
- Update Out-of-date Cartesian Product Docs by @bash in #747
- Implement Generic ParseOrNone extensions. by @FreeApophis in #745
- Disable UseWithArgumentNamesAnalyzer in Expression Trees by @bash in #751
- Implement
UpCast<T>.From(...)by @bash in #756 - Update SDK to .NET 8 by @bash in #764
- Use
IsTargetFrameworkCompatibleInstead of Listing Frameworks Manually by @bash in #767 - Rename Parseable → Parsable by @bash in #769
- Use Primary Constructors by @bash in #768
- Forgotten to set TargetFramework to .net 8 by @FreeApophis in #770
- Use collection property count access by @FreeApophis in #771
- Avoid ToAsyncEnumerable when not really necessary by @FreeApophis in #772
- Use PolySharp by @FreeApophis in #774
- Use collection expressions by @FreeApophis in #775
- Declare Funcky.XUnit incompatibility with xunit 2.5 and 2.6 releases by @FreeApophis in #778
- Implement InspectEmpty on IEnumerable. by @FreeApophis in #776
- Add missing ParseExtensions.ParseCharOrNone by @FreeApophis in #780
- Implements FindIndexOrNone and FindLastIndexOrNone on List by @FreeApophis in #781
- Add .mailmap by @bash in #786
- Mention dual licensing in readme by @bash in #787
- Mark Funcky and Funcky.Async as AOT compatible by @bash in #784
Full Changelog: 3.3.0...3.4.0
Funcky 3.3.0 | Funcky.Analyzers 1.3.0 | Funcky.Xunit 2.0.1
This is a relatively minor release focusing on convenience for our monads Option, Either and Result.
GetOrElse and OrElse for all
We've added GetOrElse and OrElse to Either and Result bringing them on par with Option.
The corresponding analyzer now also correctly suggests using these methods instead of Match for Result and Either.
Inspect for the error case
All three alternative monads Option, Either and Result now support inspecting the «error» case:
Option.InspectNone- executes a side effect only when the option isNone.Either.InspectLeft- executes a side effect only when the either is on theLeftside.Result.InspectError- executes a side effect only when the result is anError.
These methods are particularly useful for logging warnings/errors.
Funcky 3.2.0 | Funcky.Async 1.2.0
List Pattern for Option
We've added support for C# 11's List Patterns to Option<T>.
This means that you can use regular switch expressions / statements to match on options:
var greeting = person switch
{
{ FirstName: var firstName, LastName: [var lastName] } => $"Hello {firstName} {lastName}",
{ FirstName: var firstName } => $"Hi {firstName}",
};
record Person(string FirstName, Option<string> LastName);Discard
The new Discard.__ field provides a short-hand for Unit.Value to be used with switch expressions.
using static Funcky.Discard;
return __ switch
{
_ when user.IsFrenchAdmin() => "le sécret",
_ when user.IsAdmin() => "secret",
_ => "(redacted)",
};Retry with Exception
We've added overloads to the Retry and RetryAsync functions that allow retrying a function
as long as an exception is thrown.
Example from IoRetrier:
// Retries an action until the file is no longer in use.
Task RetryWhileFileIsInUseAsync(IRetryPolicy policy, Action action)
=> RetryAsync(ActionToUnit(action), exception => exception is IOException && exception.HResult == FileInUseHResult, policy);Funcky 3.1.0 | Funcky.Async 1.1.0 | Funcky.Analyzers 1.2.0
New APIs
- ✨
OptionExtensions.ToNullable✨ StreamExtenions.ReadByteOrNone- New overloads for
ElementAtOrNonethat take anIndex. - New overload for
JoinToStringthat takes anIEnumerable<string>.
.NET 7
- .NET 7 added new overloads to their
TryParseAPIs. These changes
are reflected in Funcky'sParseOrNoneAPIs. - The
ParseOrNonemethods include the new[StringSyntax]attribute from .NET 7.
Analyzers
The new Option.Match analyzer suggests simpler alternatives over custom Matches including
the all-new ToNullable extension.
Funcky 3.0.0 | Funcky.Async 1.0.0 | Funcky.XUnit 2.0.0
There's a handy Migration Guide available.
New APIs
Result.GetOrThrowEnumerableExtensions.GetNonEnumeratedCountOrNone
PriorityQueue
PriorityQueueExtensions.DequeueOrNonePeekOrNone
Traversable
The new Traverse and Sequence extension methods allow you to
«swap» the inner and outer monad (e.g. Result<Option<T>> -> Option<Result<T>>)
Memoize
The new Memoize extension function returns an IBuffer / IAsyncBuffer.
This new type represents ownership over the underlying enumerator (and is therefore IDisposable).
CycleRange and RepeatRange have also been changed to return an IBuffer.
ParseExtensions
The parse extensions have been improved with the goal of aligning more with the BCL.
Many of the changes are breaking.
- The functions now use BCL type names instead of C# type names
(e.g.ParseIntOrNonehas been renamed toParse) - The parameter names and nullability have been changed to align with the BCL.
- Added
HttpHeadersNonValidatedExtensions
IReadOnlyList / IReadOnlyCollection
Funcky now communicates materialization in the IEnumerable<T> extensions by returning
IReadOnlyList or IReadOnlyCollection. This reduces «multiple enumeration» warnings.
MaterializeChunkPartitionShuffleSlidingWindowSplitTransposeSequence.Return
Disallowing null Values
Our Option<T> type has always disallowed null values.
This has been extended to our other monads: Result<T>, Either<L, R> and Reader<E, R>.
Breaking Changes
Option.None()has been changed to a property. There's an automatic fix available for this.- Our
Matchfunctions now differentiate betweenFuncandAction.
TheActionoverloads have been renamed toSwitch. - The return type of
EnumerableExtensions.ForEachhas been changed toUnit. - Many parameter names and generic type names have been renamed in an attempt to unify naming across Funcky.
- All
Actionextensions have been moved to a new classActionExtensions. EitherOrBothhas been moved to theFunckynamespace.- The retry policies have been moved to the
Funcky.RetryPoliciesnamespace. Partitionreturns a customPartitionsstruct instead of a tuple.
Obsoleted APIs Removed
APIs that have been obsoleted during 2.x have been removed:
ObjectExtensions.ToEnumerableFuncky.GenericConstraints.RequireClassandRequireStruct- All
Try*APIs (TryGetValue,TryParse*, etc.). These APIs use theOrNonesuffix instead. Sequence.Generatehas been superceded bySequence.SuccessorsCartesianProduct
JSON Converter
We have removed the implicit System.Text.Json converter for Option<T>.
This means that you'll have to register the OptionJsonConverter yourself.
Moved to Funcky.Async
All APIs related to IAsyncEnumerable and Task have been moved to the new Funcky.Async package:
AsyncEnumerableExtensionsFunctional.RetryAsync->AsyncFunctional.RetryAsyncOption<Task>andOption<ValueTask>awaiters
Funcky.Async
AsyncSequence
This class exposes all of the same factory functions as Sequence, but for IAsyncEnumerable:
ReturnSuccessorsConcatCycleCycleRangeFromNullableRepeatRange
New IAsyncEnumerable extensions
We've worked hard towards the goal of parity between our extensions for IEnumerable and IAsyncEnumerable:
AdjacentGroupByAnyOrElseAverageOrNoneAsync/MaxOrNoneAsync/MinOrNoneAsyncChunkConcatToStringAsyncExclusiveScanInclusiveScanInspectInterleaveIntersperseJoinToStringAsyncMaterializeAsyncMemoizeMergeNoneAsyncPartitionAsyncPowerSetSequence/SequenceAsync/Traverse/TraverseAsyncShuffleAsyncSlidingWindowSplitTransposeWhereNotNullWithIndex/WithLast/WithPrevious/WithFirstZipLongest
Funcky.Xunit
- Breaking: The
Isprefix has been dropped from assertion methods for consistency with
XUnit's naming scheme for assertion methods.
Funcky 2.7.1
Deprecations
Option.None<T>(): We originally introduced theOption.None<T>method as a future proof replacement toOption<T>.Nonefor use in method groups,
because Funcky 3 changesOption<T>.Noneto a property. This turned out to be confusing to users especially because both method are always suggested in autocomplete.
Funcky 2.7.0 | Funcky.XUnit 1.0.0 | Funcky.Analyzers 1.1.0
This release is the last non-breaking release for Funcky before 3.0.
Deprecations
EnumerableExtensions.CartesianProductwill be removed in Funcky 3.- To align our naming with that of the BCL, the
ParseOrNonemethods
that return a type that has a keyword in C#int,long, etc. use the name of the BCL type instead.
Example:ParseIntOrNonebecomesParseInt32OrNone.
The old methods will be removed in Funcky 3. - In preparation for Funcky 3 we deprecated
Option<T>.Nonewhen used as method group. UseOption.None<T>instead.
New ParseOrNone extensions
With the help of a source generator we have added a lot of new ParseOrNone methods for various types from the BCL:
- Unsigned integer types
DateOnly,TimeOnlyVersion- Support for
ReadOnlySpan<T>as input - ... and more
Convenience for Either and Result
- Added implicit conversions for
EitherandResult. - Implement
InspectforEitherandResult. - Added
PartitionforIEnumerable<Either>andIEnumerable<Result>. - Added
ToStringonEitherandResult. - Implement
ToEitheronOption.
IEnumerable<T> extensions
AnyOrElse- Prefix sum:
InclusiveScanandExclusiveScan
Analyzers
This release adds two new analyzer rules:
- λ1003: Warning when certain methods, such as
Matchare used without argument labels - λ1004: Warning that suggests
.ConcatToString()over.JoinToString("")
Both of these warnings come with corresponding code fixes.
Funcky.Xunit
- Breaking: Funcky.Xunit now uses the
Funckynamespace, instead ofFuncky.Xunit. - Add assertion methods for testing
Either:FunctionalAssert.IsLeftandFunctionalAssert.IsRight.
Funcky 2.6.0 | Funcky.Analyzers 1.0.0
Analyzers
This release comes with a new package Funcky.Analyzers, which we'll use
to guide users to a better Funcky experience.
New extensions
- Add extensions
DequeueOrNoneandPeekOrNoneonQueueandConcurrentQueue. - Add extension
ConcatToStringas an alias forstring.Concat. - Add overload to
WhereSelectwith no parameter. - Add methods to convert from
EithertoOption: #439LeftOrNone: Returns the left value orNoneif the either value was right.RightOrNone: Returns the right value orNoneif the either value was left.
- Extension functions for
System.Rangeto allow the generations ofIEnumerable<T>s from Range-Syntax:foreach(var i in 1..5) { } // negative numbers are not supported from x in 5..2 from y in 1..3 select (x, y)
Improvements to Sequence
Sequence.Returnnow accepts multiple parameters:Sequence.Return(1, 2, 3)
⚠️ Sequence.Generatehas been deprecated in favour of the newly addedSequence.Successorsfunction
which includes the first element (seed) in the generated sequence.
Improvements to Option
- Add
Option.FromBooleanto create anOption<T>from a boolean.
Improvements to Result
The behaviour of the Result.Error constructor has been changed regarding exceptions
with an already set stack trace. The original stack trace is now preserved.
Previously this resulted in the stacktrace being replaced (.NET < 5.0) or an error (.NET ≥ 5.0).
Improvements to Either
- Add
Either.Flipto swaps left with right.
Tooling
- Funcky automatically adds global usings for the most important namespaces of funcky
when theFunckyImplicitUsingsproperty is set. This requires .NET SDK ≥ 6.0 and C# ≥ 10.0. - Funcky now supports trimming for self-contained deployments.
Option<T>now works with the new System.Text.Json source generation.- The
Funckypackage now supports Source Link and deterministic builds. - The symbols package is now finally working again.