[Haskell-cafe] Reinventing the wheel? Does any existing package provide an applicatively lifted (>>) ?

Isaac Elliott isaace71295 at gmail.com
Thu Sep 28 22:46:39 UTC 2017


On Fri, Sep 29, 2017 at 2:56 AM Viktor Dukhovni <ietf-dane at dukhovni.org>
wrote:

>
> Can you explain that qualification?
>

I mean that you don't need to use (>>=) on the IO inside the RowParser.

The composition of two Applicatives is also an Applicative. If you upgrade
one to Monad this is no longer true. Since you're only using (>>)
(which is really an Applicative operation in disguise), we don't need to
worry here.


> Indeed this works, and looks more clear than some new unfamiliar operator.
> This seems to have no measurable run-time cost.  Is it reasonable to expect
> that under the covers no objects boxed as (Compose _) are ever created, and
> that Compose here is just compile-time syntactic sugar for applying (*>) at
> the desired layer, so that:
>
>    getCompose $ Compose (Foo Bar a)
>              *> Compose (Foo Bar b)
>              *> Compose (Foo Bar c)
>              ...
>              *> Compose (Foo Bar z)
>
> just compiles down to Foo (Bar a *> Bar b *> Bar c *> ... *> Bar z)?
> Where, in my case, Foo is "RowParser" and Bar is IO?
>

If we tried to write a typeclass instance for "composition of
applicatives", it might look something like this:

instance (Applicative f, Applicative g) => forall a. Applicative (f (g a))
where
  ...

But we're not allowed to write such an instance. To get around this, a
newtype is created:

newtype Compose f g a = Compose { getCompose :: f (g a) }

and a valid instance can be written:

instance (Applicative f, Applicative g) => Applicative (Compose f g) where
  pure = Compose . pure . pure
  a <*> b = Compose $ liftA2 (<*>) a b

You are correct in assuming it has no runtime cost- at runtime the `f (g
a)` is passed around as normal, but at compile
time, `Compose f g a` is considered distinct to `f (g a)`.

Due to this typeclass instance,

getCompose $
Compose a *>
Compose b *>
Compose c

is equivalent to

liftA2 (*>) (liftA2 (*>) a b) c
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20170929/4e1cf22b/attachment.html>


More information about the Haskell-Cafe mailing list