Brent Yorgey
However, guardA is not as useful as guard, and it is not possible to do the equivalent of the example shown using a list comprehension with a guard. The reason is that whereas monadic computations can make use of intermediate computed values to decide what to do next, Applicative computations cannot. So there is no way to generate values for x and y and then pass them to 'guardA' to do the filtering. guardA can only be used to conditionally abort an Applicative computation using information *external* to the Applicative computation; it cannot express a condition on the intermediate values computed by the Applicative computation itself.
To continue this story, from most applicative functors you can construct a category, which is interesting for non-monads. Let's examine the SparseStream functor, which is not a monad: data SparseStream a = SparseStream { headS :: Maybe a, tailS :: SparseStream a } This is an applicative functor, instance Applicative SparseStream where pure x = let str = SparseStream (Just x) str in str SparseStream f fs <*> SparseStream x xs = SparseStream (f <*> x) (fs <*> xs) but with a little extension it becomes a category, the wire category: newtype Wire a b = Wire (a -> (Maybe b, Wire a b)) This is like SparseStream, but for each head/tail pair it wants an argument. Given a Category instance you can now actually make use of guardA without resorting to monadic combinators: guardA p . myStream This is conceptually how Netwire's applicative FRP works and how events are implemented. Greets, Ertugrul -- Not to be or to be and (not to be or to be and (not to be or to be and (not to be or to be and ... that is the list monad.