question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Calling .Sequence on a left state Either<L, Task<R>> is returning bottom value

See original GitHub issue

Example code:

var before = Left<string, Task<int>>("Failed");
var after = await before.Sequence();

I’m expecting after to be a left value of the type Either<string, int>, but in reality it is a bottom value.

Nuget version: 3.1.15

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
louthycommented, Feb 28, 2020

Isn’t that because it isn’t a monad that has a “zero” but a monoid?

No, that’s ‘Empty’. Monads in language-ext follow the MonadPlus type-class design. But, it’s not valid for all monads, so things like this happens. It’s just a limitation that I’ve had to deal with when trying to formalise the type-class/class-instance system. I think there’s a better approach (via code-gen), but it takes time to get all this into my head (then implementing it is a whole other bundle of joy)

-- | Monads that also support choice and failure.
class (Alternative m, Monad m) => MonadPlus m where
   -- | The identity of 'mplus'.  It should also satisfy the equations
   --
   -- > mzero >>= f  =  mzero
   -- > v >> mzero   =  mzero
   --
   -- The default definition is
   --
   -- @
   -- mzero = 'empty'
   -- @
   mzero :: m a
   mzero = empty

   -- | An associative operation. The default definition is
   --
   -- @
   -- mplus = ('<|>')
   -- @
   mplus :: m a -> m a -> m a
   mplus = (<|>)
0reactions
louthycommented, Mar 5, 2020

The latest beta has the issues in this thread fixed:

var before = Left<string, Task<int>>("Failed");
var after = await before.Sequence();  // Left("Failed")
Either<string, Seq<int>> r1 = Prelude.Seq(1,2,3);
Seq<Either<string, int>> r2 = r1.Sequence(); // [Right(1), Right(2), Right(3)]
Either<string, Seq<int>> r3 = r2.Sequence(); // Right(Seq(1,2,3))

Either<string, Seq<int>> l1 = "left";
Seq<Either<string, int>> l2 = l1.Sequence(); // []
Either<string, Seq<int>> l3 = l2.Sequence(); // Right([])

The notion of symmetry when calling Sequence twice isn’t a contract of the function, and couldn’t possibly be maintained for all pairs of monads. Traverse and Sequence both work by applying the monad rules of the inner and outer type repeatedly for the all of the items in the transformer type; that can be destructive in the case of monad can short-cut an operation (Option, Either, etc.), and so data can be lost in the operation, that obviously means it can’t be recovered by calling Sequence again.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Deadlock from calling Task.Result · Issue #317
You're asynchronously getting values in a synchronous method, so a deadlock seems pretty natural to occur there, unless I'm missing something.
Read more >
EQL syntax reference | Elasticsearch Guide [8.9]
Returns true if the value to the left of the operator is less than or equal to the value to the right. Otherwise...
Read more >
SEQUENCE function in Excel - auto generate number series
See how to use the Excel SEQUENCE function to create a number series starting at a specific value.
Read more >
Fantas, Eel, and Specification 12: Traversable
A function that transforms one Functor into another without touching the inner value is called a natural transformation! t(u.sequence(F)) ...
Read more >
Getting Func-ey Part 4 - Practical effect manipulation
The person had introduced a bug in that PR. Yes the result is returned in order but it's not necessarily executed in order....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found