Language-Ext 5.0 alpha-3 #1311
louthy
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Bug fixing and TODO resolving release, with some minor featurettes!
For those that don't know yet (and there's no reason to think you should, because I haven't announced it yet) -- the Pipes
Effect
system now has the ability to lift any monad into its stack (previously it only allowedAff
to be lifted). It is now a general monad transformer likeReaderT
,OptionT
,EitherT
, etc.As, with all monad-transfomers, when you 'run' the transformer, it generates the lifted monad. You can think of this being like a mini-compiler that takes the monad stack and compiles down to the inner-most monad, which can then just be run as normal.
The problem for Pipes is that there's usually lots of recursion, repetition (using
repeat
,retry
), or iteration (usingyieldAll
, etc.). This is problematic when you don't know anything about the inner monad. The transformer can't run the inner monad, because it only has access to theMonad
interface (Bind
) and the inherited interfaces ofApplicative
andFunctor
(Apply
,Action
,Map
, andPure
). So, doing iteration requires recursion, and recursion blows the stack in C#.Anyway, now Pipes has internal support for any
Foldable
. That meansyieldAll(...)
can take a sequence from any foldable (Range
,EnumerableM
,HashMap
,HashSet
,Lst
,Map
,Seq
,Either
,Option
,Validation
,Identity
, ... and any you write) and yield the values within the structure through the pipe. Functions likerepeat(ma)
- which continually repeat an operation until it fails - have also been implemented internally as something that iterates over an infinite foldable.This functionality has been enabled by adding a new method to the
Applicative
trait:Actions
. You might know the existingAction(K<M, A> ma, K<M, B> mb)
method that runs the first applicative (ma
), ignores its result, and then runs the second applicativemb
, returning its result.Actions
instead takes anIEnumerable<K<M, A>>
:It runs each applicative action and ignores its result, returning the result of the last item. That means a sequence of
Proxy
values (Proxy
is the monad-transformer for pipes) can be mapped - the map will just run (usingRunEffect
) the Proxy - producing a sequence of whatever the lifted inner-monad is for theProxy
. This lazy sequence of monads can then be invoked by callingActions
on it, which will lazily walk the sequence, evaluating the inner-monad one-by-one.There is a default implementation, but it has the same lack of knowledge that Pipes had, so it should be overridden for computation based applicatives (that usually need invoking with without an argument). Here's the override for
Eff<RT, A>
:You can see how:
And so, if you want to use your own monads with Pipes then you should implement
Actions
.There's still more to do with Pipes, but all of the examples in
EffectsExamples
now work, which is a good sign!This discussion was created from the release Language-Ext 5.0 alpha-3.
Beta Was this translation helpful? Give feedback.
All reactions