Code Monkey home page Code Monkey logo

Comments (9)

raimohanska avatar raimohanska commented on May 20, 2024

I added Monoid for EventStream. It already had concat so I only had to add a synonym EventStream.empty for Bacon.never. What a fun excercise!

from fantasy-land.

Twisol avatar Twisol commented on May 20, 2024

In Haskell, you can declare Monad without Applicative. Why not in Fantasy Land?

This is a known issue, and Haskellers are generally unsatisfied with the current state of affairs. The Haskell situation is an artifact of monads being used in Haskell early on (to control side-effects and I/O), before applicatives were also found to be generally useful. The Monad and Applicative class instances are expected to agree even though the standard library doesn't require it. Mathematically, all monads are applicative functors by definition.

I don't know Bacon.js well enough to suggest any specific alternatives. Does your flatMap meet the Monad axioms in all cases (barring unavoidable semantics of mutation)? What if you implemented flatMap in terms of combine/zip - what effects would that have on the monadic semantics?

from fantasy-land.

markandrus avatar markandrus commented on May 20, 2024

chain and map give you ap. In the Fantasy Land spec:

  • Applicative's ap; derivable as function(m) { return this.chain(function(f) { return m.map(f); }); }

Did you try this default definition? There may be multiple and sometimes more useful ways to write ap. EventStream might be one such case, but I don't know Bacon.js.

from fantasy-land.

raimohanska avatar raimohanska commented on May 20, 2024

Guys, thanks for your replies!

@markandrus My implementation of EventStream.ap is identical to the default one. If I have to choose one, I might go for the zip based approach, though. That might be useful for someone :)
@Twisol I'm tempted to say it meets the Monad axioms. Are we talking about the laws in here?
@Twisol you cannot implement flatMap in terms of combine/zip, can you?

from fantasy-land.

raimohanska avatar raimohanska commented on May 20, 2024

The issue is not whether I can implement Applicative, but more that I'd rather not because of the many different possible ways.

Like, if [] is Applicative, should it use >>= or zip? Depends on situation, probably.

from fantasy-land.

Twisol avatar Twisol commented on May 20, 2024

@raimohanska RIght, those laws. It's best if you semi-rigorously prove that those axioms hold for your implementation, since it's easy to miss important edge cases.

When I said "implement it in terms of combine/zip", I meant that there may be a Monad implementation associated with the combine/zip-based Applicative you prefer, so you may want to start there and find a new flatMap for which the automatically-provided ap is equivalent to the new one. See if the semantics for the new flatMap make sense.

It may turn out that either of your ap and flatMap definitions don't preserve the appropriate axioms, or that you really do have two interesting sets of instances. Integers have at least two Monoid instances - Sum and Product - so this isn't obviously impossible. I would be a little surprised though.

from fantasy-land.

puffnfresh avatar puffnfresh commented on May 20, 2024

Yes, Haskell stuffed up by not realising the hierarchy of Apply => Applicative => Monad. Fantasy Land doesn't have that problem.

Anyway, even in Haskell, for every Monad you can get an Applicative - the opposite is of course not true.

instance Monad m => Applicative (WrappedMonad m) where
    pure = WrapMonad . return
    WrapMonad f <*> WrapMonad v = WrapMonad (f `ap` v)

Where Haskell's ap is actually defined over Monad:

ap :: (Monad m) => m (a -> b) -> m a -> m b
ap = liftM2 id

liftM2  :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 f m1 m2 = do
  x1 <- m1
  x2 <- m2
  return (f x1 x2)

So if we can implement chain and of for EventStream but the above doesn't work, then the Monad laws must be broken somewhere 😦

And yes, things can have multiple Applicatives. That's what I was trying to get at with this part of the spec:

If there's more than a single way to implement the methods and
laws, the implementation should choose one and provide wrappers for
other uses.

Haskell does the same thing:

newtype ZipList a = ZipList { getZipList :: [a] }

instance Applicative ZipList where
    pure x = ZipList (repeat x)
    ZipList fs <*> ZipList xs = ZipList (zipWith id fs xs)

I'd say the Applicative for a data type should do the same as the Monad (if one is defined). That'd be the least surprising. Provide a wrapper for the other behaviour(s).

from fantasy-land.

philipnilsson avatar philipnilsson commented on May 20, 2024

An interesting feature of Applicatives is that they can not be used to change the 'control flow'. E.g. for IO

(\fire -> if fire then a else b) <$> fireZeMissiles <*> petTheKoala

will result in the side effects of fireZeMissiles always executing, even if fire is false. The applicative interface could perhaps (for IO) define a combinator that runs its arguments in parallell, as the order things complete does not affect the result.

Perhaps one could standardize on a "parallel applicative" type class, which the zip-applicative for lists and event streams could fulfill, as they are in a sense also "parallel".

from fantasy-land.

SimonRichardson avatar SimonRichardson commented on May 20, 2024

I'm closing this one, reopen if you wish to suggest other wise.

from fantasy-land.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.