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.

Monadic vs. applicative traverse/sequence

See original GitHub issue

FSharpPlus contains traverse and sequence. I assume they are monadic. Is there support for applicative versions? If not, would it make sense to add?

For details, see https://fsharpforfunandprofit.com/posts/elevated-world-4/#applicative-vs-monadic-versions-of-traverse

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:9 (9 by maintainers)

github_iconTop GitHub Comments

3reactions
gustycommented, Dec 18, 2019

That blog post is misleading.

Applicative and Monadic versions are different internally, in terms of implementation, externally the sole difference should be that the Monadic version requires that the type is a Monad.

Since all Monads are Applicatives our implementation is based on the latter, to avoid unnecessary restrictions.

But having said that, it’s important to remark that contrary to what he says, both Applicative and Monadic implementations should return exactly the same results.

I think he’s misusing the names to signify that the applicative implementation is based on Applicative Validation, which is a different Applicative for errors. See https://github.com/fsprojects/FSharpPlus/issues/51 which is already implemented.

PS: You are not the first person I know that got confusing after reading that post, I think we should ask the author to rectify. He should find another name to distinguish, not just Applicative, maybe Accumulative.

1reaction
gustycommented, Dec 18, 2019

Yes, I understand your concern but if you think about it, it’s a logical problem.

We can’t have two different implementations on the same type and use generic operators at the same time.

When you have two or more implementations on the same type there are 2 options:

  • You don’t use generic operators, you create a specific operator for the implementation you want. This is the approach most non-generic F# libraries take, some of them use the same identifier for the function/operator but in fact they are different, they force you open different namespaces to switch between operators with the same identifier but different implementations.

  • You choose one default implementation for the type and use a wrapper type for the other implementations. This is the approach we take here and also other generic libraries in other languages (Purescript, Scala, Haskell, Agda, Idris, etc).

Why didn’t we choose the Accumulative errors as the default implementation?

Because it’s not monadic. Had we choose that one we were not able to create a Result CE. Or we could have use the other implementation for the Monad as shown in the post, but that would break a lot of rules and would be impossible to reason about the code. Other libraries in other languages took the same path.

Now, we can consider some mixed functionality by providing non-generic operators namespaces. This is a path we never went into because this library started initially as a generic one, but it has evolved in the non-generic field as well, so at some point we could consider it. If you feel like, you can open a new issue proposing these changes.

Note this is not an issue that involves only applicative validation, same situation exists with seqs, lists, arrays (which have an alternative point-wise applicative ZipList), numeric types also have an alternative monoid that does multiplication instead of addition, function default to Writer but they could implement State as well.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Difference between Monad and Applicative in Haskell
The key distinction of Monads is the ability to choose between different paths in computation (not just break out early). Depending on a...
Read more >
Chapter 12. Applicative and traversable functors
For example, a monadic parser allows for context-sensitive grammars while an applicative parser can only handle context-free grammars. Monad makes effects first ...
Read more >
The underrated applicative functor
Once monads are mastered, applicative functors may appear as intermediary abstractions. In reality, they allow sequential OR parallel ...
Read more >
The difference between Applicative and Monad is that ...
Applicatives normalize products, while monads normalize exponentials. Applicative takes a product of m s of any length (even an empty product () ) ......
Read more >
Implementing a monad is only 30% of the deal. Being able ...
Being able to abstract over monads (and other type constructors) ... that's the part that really matters. C# is not expressive enough for...
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