Brent Yorgey <[email protected]> wrote:

> 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.

Attachment: signature.asc
Description: PGP signature

_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to