Brent Yorgey <byorgey at seas.upenn.edu> 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120913/1259a6ca/attachment.pgp>