[GHC] #13191: Make liftA2 a method of Applicative
GHC
ghc-devs at haskell.org
Wed Jan 16 16:57:16 UTC 2019
#13191: Make liftA2 a method of Applicative
-------------------------------------+-------------------------------------
Reporter: dfeuer | Owner: dfeuer
Type: feature request | Status: closed
Priority: normal | Milestone: 8.2.1
Component: Core Libraries | Version: 8.0.1
Resolution: fixed | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s): Phab:D3031
Wiki Page: |
-------------------------------------+-------------------------------------
Old description:
> Some functors support implementations of `liftA2` that are considerably
> faster than the usual definition. Furthermore, some people see `liftA2`
> as more intuitive and fundamental to the idea of `Applicative` than `<*>`
> is.
>
> This has been discussed on the libraries list in
> https://mail.haskell.org/pipermail/libraries/2017-January/027579.html and
> (as an official proposal) in
> https://mail.haskell.org/pipermail/libraries/2017-January/027612.html.
> All who expressed an opinion favored the proposal. One (David Menendez)
> specified that his support was weak. The others (Conal Elliot, Kris
> Nuttycombe, Wren Romano, Bardur Arantsson, and Mario Blažević) either
> supported the proposal strongly or merely indicated they were "+1". Conal
> Elliot wrote:
> [[BR]]
> [[BR]]
>
> > +1.
> >
> > I also sometimes define a specialized `liftA2` and then use it to
> define
> > `(<*>)`, which then gets used to define the real `liftA2`.
> >
> > I think of `liftA2` as playing a role similar to `foldMap` and
> `traverse`, while
> > `(<*>)` corresponds to `fold` and `sequenceA`. The first three self-
> compose
> > nicely: `liftA2.liftA2.liftA2`, `foldMap.foldMap.foldMap`, and
> > `traverse.traverse.traverse`. With functor composition, it's so much
> nicer to
> > write `liftA2.liftA2` (in the style of `Functor`, `Foldable`, and
> `Traversable`)
> > rather than `liftA2 (<*>)`.
> [[BR]]
>
> Wren Romano wrote
> [[BR]]
> [[BR]]
>
> > I'm also all for adding liftA2 to the class and have noticed this
> > inefficiency/asymmetry when working on the class hierarchies for other
> > languages
> [[BR]]
>
> Kris NuttyCombe wrote
> [[BR]]
> [[BR]]
>
> > I'm in favor of this change. From my perspecive, liftA2 is actually the
> > fundamental Applicative operation, an <*> is merely a convenient
> > isomorphism. When I'm teaching, showing the symmetry between the
> following
> > always seems to help students:
> >
> > fmap :: (a -> b) -> f a -> f b
> > liftA2 :: (a -> b -> c) -> f a -> f b -> f c
> > flip (>>=) :: (a -> f b) -> f a -> f b
> >
> > <*> is obviously exceptionally useful in practice. But liftA2 seems
> like the
> > more essential shape of that operation.
New description:
Some functors support implementations of `liftA2` that are considerably
faster than the usual definition. Furthermore, some people see `liftA2` as
more intuitive and fundamental to the idea of `Applicative` than `<*>` is.
This has been discussed on the libraries list in
https://mail.haskell.org/pipermail/libraries/2017-January/027579.html and
(as an official proposal) in
https://mail.haskell.org/pipermail/libraries/2017-January/027612.html. All
who expressed an opinion favored the proposal. One (David Menendez)
specified that his support was weak. The others (Conal Elliott, Kris
Nuttycombe, Wren Romano, Bardur Arantsson, and Mario Blažević) either
supported the proposal strongly or merely indicated they were "+1". Conal
Elliott wrote:
[[BR]]
[[BR]]
> +1.
>
> I also sometimes define a specialized `liftA2` and then use it to define
> `(<*>)`, which then gets used to define the real `liftA2`.
>
> I think of `liftA2` as playing a role similar to `foldMap` and
`traverse`, while
> `(<*>)` corresponds to `fold` and `sequenceA`. The first three self-
compose
> nicely: `liftA2.liftA2.liftA2`, `foldMap.foldMap.foldMap`, and
> `traverse.traverse.traverse`. With functor composition, it's so much
nicer to
> write `liftA2.liftA2` (in the style of `Functor`, `Foldable`, and
`Traversable`)
> rather than `liftA2 (<*>)`.
[[BR]]
Wren Romano wrote
[[BR]]
[[BR]]
> I'm also all for adding liftA2 to the class and have noticed this
> inefficiency/asymmetry when working on the class hierarchies for other
> languages
[[BR]]
Kris NuttyCombe wrote
[[BR]]
[[BR]]
> I'm in favor of this change. From my perspecive, liftA2 is actually the
> fundamental Applicative operation, an <*> is merely a convenient
> isomorphism. When I'm teaching, showing the symmetry between the
following
> always seems to help students:
>
> fmap :: (a -> b) -> f a -> f b
> liftA2 :: (a -> b -> c) -> f a -> f b -> f c
> flip (>>=) :: (a -> f b) -> f a -> f b
>
> <*> is obviously exceptionally useful in practice. But liftA2 seems like
the
> more essential shape of that operation.
--
Comment (by conal):
Fix spelling of my last name ("Elliott").
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13191#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list