Breaking change: OptionAsync await + Producer.merge
This is a fixes release.
OptionAsync
I have brought forward a change to OptionAsync
that I was saving for v5
: the removal of the async-awaiter. You can't now await
an OptionAsync
. The resulting value wasn't clear, and honestly the async
/await
machinery is really quite shonky outside of using it for Tasks.
I have made the OptionAsync
implementation aware of nullable references, and so you can now await
the Value
property instead:
public Task<A?> Value
That will reproduce the same behaviour as before. You can still await
the ToOption()
method, which returns a Task<Option<A>>
, if you want to do matching on the underlying option. Or call the various Match*
methods.
This release fixes the following issues:
Producer.merge
error handling
Producer merging was silently ignoring errors. They now exit and return the first error and shutdown other producers they were merged with. Merged producers also listen for cancellation correctly now.
Finally, you can only merge produces with a bound value of Unit
. This is to stop the silent dropping of their return value as well as the need to provide a final (bound) value for merged producers, which doesn't really make sense. That also means the +
operator can't work any more because it can't be defined for the Producer<..., A>
type. So you must use Producer.merge
.
This fixes an issue mentioned in: #1177
repeatM
doesn't cause a stack-overflow
Certain elements of the Pipes
capability of language-ext are direct ports from the Haskell Pipes library, which uses recursion everywhere. repeatM
was causing a stack-overflow on usage, this is now fixed.
Example usage:
public static Effect<Runtime, Unit> effect =>
Producer.repeatM(Time<Runtime>.nowUTC) | writeLine<DateTime>();
static Consumer<Runtime, X, Unit> writeLine<X>() =>
from x in awaiting<X>()
from _ in Console<Runtime>.writeLine($"{x}")
from r in writeLine<X>()
select r;
repeat
improvements
Removed the Repeat
case from the Pipes DSL which simplifies it and brings it closer to the Haskell version. Updated the repeat
combinator function to use the same Enumerate
case that yieldAll
uses. This has benefits that it doesn't spread out when composed with other Proxy
types. This is should mean it's easier to pick bits of the expression to repeat, rather than the whole effect being repeated due to the spread.
Trampoline
Added trampolining functionality. It's relatively light at the moment, I am considering approaches to enable genuine recursion in the effects system. Don't rely on this, it may be removed if it doesn't prove useful and almost certainly will have API changes if it stays.