-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Static Land interop Observable
definition is wrong
#286
Comments
Yeah, I'm still not sure what is the right call here. I don't use Static or Fantasy Land in anything real, it always was experimental/academic for me. So it's hard to tell what is the best solution from the practical point of view. We could expose two modules, but that would complicate things. On the other hand, the single module is not quite correct. One of the reasons why I did a single module initially is that the sequential |
@polytypic I'm not sure I agree that
https://typelevel.org/cats/typeclasses/parallel.html
https://hackernoon.com/functors-and-applicatives-b9af535b1440
That's a quote from "Scala in Depth" by Josh Suereth, discussed here: https://stackoverflow.com/questions/12184373/how-do-applicative-functors-tie-in-with-parallelizing-algorithms-scala-and-sca On the other hand I found this comment on Reddit that argues that an implementer should maybe consider making an
Replies to that comment point out some counterexamples. There is also a discussion of "sequencing of effects" in Haskell on Wikibooks that sheds some light on the issue. The gist is that the result of https://en.wikibooks.org/wiki/Haskell/Applicative_functors#Sequencing_of_effects My interpretation of what I have read is that there is no absolute rule about the relationship between |
That is entirely acceptable. I do use Static Land in real projects that are in production.
Yes, having more modules is more complex in a sense. However, sometimes there is essential complexity that must not go away.
I'll give you a pair of interconnected examples. First of all, according to the laws, the functions (written in naïve style for clarity) const sequenceA = (A, ops) =>
A.ap(A.map(R.prepend, R.head(ops)), sequenceA(A, R.tail(ops))) const sequenceM = (M, ops) =>
M.chain(
h => M.map(R.prepend(h), sequenceM(M, R.tail(ops)),
R.head(ops)
) are equivalent (with respect to sequencing of effects) for every Monad sequenceA(M, ops) === sequenceM(M, ops) An application of the laws that relate algebraic structure to each other is the ability to refactor expressions between various equivalent forms. Of the above two definitions for sequencing, the former is preferable, because it is more polymorphic. It works not just for every applicative, but for every monad as well, while the latter version only works for monads. Now, let's think of a more concrete example: simple sequential asynchronous programming. As hinted in those slides, observables can be used for such programming. The gist is that each observable in such a "mode of use of observables" emits at most one value. (This way the duplication of events does not happen.) However, if you'd use the law-breaking |
Note that my point isn't that So, instead of having one broken
As mentioned above, the Static Land spec gives such a rule. One basis for the rule is simply that every monad gives rise to an applicative via the definition given e.g. in Joseph Abrahamson's SO answer: ap :: Monad m => m (a -> b) -> m a -> m b
ap mf ma = do
f <- mf
a <- ma
return (f a) As also discussed in Abrahamson's answer, there are cases where an applicative instance cannot have a corresponding monad instance. Another basis is given in a discussions on sequencing of effects, which boils down to:
|
Hm, right, in the case of one-value observables sequential Let's discuss how exactly we could fix this. I think we shouldn't change |
Like a comment in the current definition says, the definition is wrong:
I can see the "good intention" behind the above definition, but a major advantage of Static Land is precisely the fact that for a single type you can simply have as many different algebra module instances as needed:
Observables support multiple different algebras. For example, basically every
flatMapXXX
operation induces a Monad with different semantics. With Static Land, each of those can be supported as different algebra modules (all of them fully correct) from which the user can then pick and choose the appropriate one depending on which semantics are needed.So, why is the above definition wrong? Because it breaks the sequential semantics of the chain. Let's say that you wish to perform a sequence of, say, database operations using the
Observable
definition. You should be able to do that with an applicativesequence
function, but now you cannot, because the above definition executes the operations in parallel, rather than sequentially.Of course, another major advantage of Static Land is that this issue can be worked around simply by providing the proper algebra modules outside of the library core.
The text was updated successfully, but these errors were encountered: